Robot Framework Integrated Development Environment (RIDE)
settings.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import os
17 import random
18 import sys
19 import time
20 
21 from robotide.lib.robot.errors import DataError, FrameworkError
22 from robotide.lib.robot.output import LOGGER, loggerhelper
23 from robotide.lib.robot.result.keywordremover import KeywordRemover
24 from robotide.lib.robot.result.flattenkeywordmatcher import validate_flatten_keyword
25 from robotide.lib.robot.utils import (abspath, escape, format_time, get_link_path,
26  html_escape, is_list_like, py2to3,
27  split_args_from_name_or_path)
28 
29 from .gatherfailed import gather_failed_tests, gather_failed_suites
30 
31 
32 @py2to3
33 class _BaseSettings():
34 
37  _cli_opts = {'RPA' : ('rpa', None),
38  'Name' : ('name', None),
39  'Doc' : ('doc', None),
40  'Metadata' : ('metadata', []),
41  'TestNames' : ('test', []),
42  'TaskNames' : ('task', []),
43  'ReRunFailed' : ('rerunfailed', 'NONE'),
44  'ReRunFailedSuites': ('rerunfailedsuites', 'NONE'),
45  'SuiteNames' : ('suite', []),
46  'SetTag' : ('settag', []),
47  'Include' : ('include', []),
48  'Exclude' : ('exclude', []),
49  'Critical' : ('critical', None),
50  'NonCritical' : ('noncritical', None),
51  'OutputDir' : ('outputdir', abspath('.')),
52  'Log' : ('log', 'log.html'),
53  'Report' : ('report', 'report.html'),
54  'XUnit' : ('xunit', None),
55  'SplitLog' : ('splitlog', False),
56  'TimestampOutputs' : ('timestampoutputs', False),
57  'LogTitle' : ('logtitle', None),
58  'ReportTitle' : ('reporttitle', None),
59  'ReportBackground' : ('reportbackground',
60  ('#9e9', '#9e9', '#f66')),
61  'SuiteStatLevel' : ('suitestatlevel', -1),
62  'TagStatInclude' : ('tagstatinclude', []),
63  'TagStatExclude' : ('tagstatexclude', []),
64  'TagStatCombine' : ('tagstatcombine', []),
65  'TagDoc' : ('tagdoc', []),
66  'TagStatLink' : ('tagstatlink', []),
67  'RemoveKeywords' : ('removekeywords', []),
68  'FlattenKeywords' : ('flattenkeywords', []),
69  'PreRebotModifiers': ('prerebotmodifier', []),
70  'StatusRC' : ('statusrc', True),
71  'ConsoleColors' : ('consolecolors', 'AUTO'),
72  'StdOut' : ('stdout', None),
73  'StdErr' : ('stderr', None),
74  'XUnitSkipNonCritical' : ('xunitskipnoncritical', False)}
75 
78  _output_opts = ['Output', 'Log', 'Report', 'XUnit', 'DebugFile']
79 
80  def __init__(self, options=None, **extra_options):
81  self.start_timestampstart_timestamp = format_time(time.time(), '', '-', '')
82  self._opts_opts = {}
83  self._cli_opts_cli_opts_cli_opts = self._cli_opts_cli_opts_cli_opts.copy()
84  self._cli_opts_cli_opts_cli_opts.update(self._extra_cli_opts)
85  self._process_cli_opts_process_cli_opts(dict(options or {}, **extra_options))
86 
87  def _process_cli_opts(self, opts):
88  for name, (cli_name, default) in self._cli_opts_cli_opts_cli_opts.items():
89  value = opts[cli_name] if cli_name in opts else default
90  if isinstance(default, list):
91  # Copy mutable values and support list values as scalars.
92  value = list(value) if is_list_like(value) else [value]
93  self[name] = self._process_value_process_value(name, value)
94  self['TestNames'] += self['ReRunFailed'] + self['TaskNames']
95  self['SuiteNames'] += self['ReRunFailedSuites']
96 
97  def __setitem__(self, name, value):
98  if name not in self._cli_opts_cli_opts_cli_opts:
99  raise KeyError("Non-existing option '%s'." % name)
100  self._opts_opts[name] = value
101 
102  def _process_value(self, name, value):
103  if name == 'ReRunFailed':
104  return gather_failed_tests(value)
105  if name == 'ReRunFailedSuites':
106  return gather_failed_suites(value)
107  if name == 'LogLevel':
108  return self._process_log_level_process_log_level(value)
109  if value == self._get_default_value_get_default_value(name):
110  return value
111  if name == 'Doc':
112  return self._escape_as_data_escape_as_data(value)
113  if name in ['Metadata', 'TagDoc']:
114  if name == 'Metadata':
115  value = [self._escape_as_data_escape_as_data(v) for v in value]
116  return [self._process_metadata_or_tagdoc_process_metadata_or_tagdoc(v) for v in value]
117  if name in ['Include', 'Exclude']:
118  return [self._format_tag_patterns_format_tag_patterns(v) for v in value]
119  if name in self._output_opts_output_opts and (not value or value.upper() == 'NONE'):
120  return None
121  if name == 'OutputDir':
122  return abspath(value)
123  if name in ['SuiteStatLevel', 'ConsoleWidth']:
124  return self._convert_to_positive_integer_or_default_convert_to_positive_integer_or_default(name, value)
125  if name == 'VariableFiles':
126  return [split_args_from_name_or_path(item) for item in value]
127  if name == 'ReportBackground':
128  return self._process_report_background_process_report_background(value)
129  if name == 'TagStatCombine':
130  return [self._process_tag_stat_combine_process_tag_stat_combine(v) for v in value]
131  if name == 'TagStatLink':
132  return [v for v in [self._process_tag_stat_link_process_tag_stat_link(v) for v in value] if v]
133  if name == 'Randomize':
134  return self._process_randomize_value_process_randomize_value(value)
135  if name == 'MaxErrorLines':
136  return self._process_max_error_lines_process_max_error_lines(value)
137  if name == 'RemoveKeywords':
138  self._validate_remove_keywords_validate_remove_keywords(value)
139  if name == 'FlattenKeywords':
140  self._validate_flatten_keywords_validate_flatten_keywords(value)
141  if name == 'WarnOnSkipped':
142  with LOGGER.cache_only:
143  LOGGER.warn("Option '--warnonskippedfiles' is deprecated and "
144  "has no effect. Nowadays all skipped files are "
145  "reported.")
146  return value
147 
148  def _escape_as_data(self, value):
149  return value
150 
151  def _process_log_level(self, level):
152  level, visible_level = self._split_log_level_split_log_level(level.upper())
153  self._opts_opts['VisibleLogLevel'] = visible_level
154  return level
155 
156  def _split_log_level(self, level):
157  if ':' in level:
158  level, visible_level = level.split(':', 1)
159  else:
160  visible_level = level
161  self._validate_log_level_and_default_validate_log_level_and_default(level, visible_level)
162  return level, visible_level
163 
164  def _validate_log_level_and_default(self, log_level, default):
165  if log_level not in loggerhelper.LEVELS:
166  raise DataError("Invalid log level '%s'" % log_level)
167  if default not in loggerhelper.LEVELS:
168  raise DataError("Invalid log level '%s'" % default)
169  if not loggerhelper.IsLogged(log_level)(default):
170  raise DataError("Default visible log level '%s' is lower than "
171  "log level '%s'" % (default, log_level))
172 
173  def _process_max_error_lines(self, value):
174  if not value or value.upper() == 'NONE':
175  return None
176  value = self._convert_to_integer_convert_to_integer('maxerrorlines', value)
177  if value < 10:
178  raise DataError("Option '--maxerrorlines' expected an integer "
179  "value greater that 10 but got '%s'." % value)
180  return value
181 
182  def _process_randomize_value(self, original):
183  value = original.lower()
184  if ':' in value:
185  value, seed = value.split(':', 1)
186  else:
187  seed = random.randint(0, sys.maxsize)
188  if value in ('test', 'suite'):
189  value += 's'
190  if value not in ('tests', 'suites', 'none', 'all'):
191  self._raise_invalid_option_value_raise_invalid_option_value('--randomize', original)
192  try:
193  seed = int(seed)
194  except ValueError:
195  self._raise_invalid_option_value_raise_invalid_option_value('--randomize', original)
196  return value, seed
197 
198  def _raise_invalid_option_value(self, option_name, given_value):
199  raise DataError("Option '%s' does not support value '%s'."
200  % (option_name, given_value))
201 
202  def __getitem__(self, name):
203  if name not in self._opts_opts:
204  raise KeyError("Non-existing option '%s'." % name)
205  if name in self._output_opts_output_opts:
206  return self._get_output_file_get_output_file(name)
207  return self._opts_opts[name]
208 
209 
215  def _get_output_file(self, option):
216  name = self._opts_opts[option]
217  if not name:
218  return None
219  if option == 'Log' and self._output_disabled():
220  self['Log'] = None
221  LOGGER.error('Log file is not created if output.xml is disabled.')
222  return None
223  name = self._process_output_name_process_output_name(option, name)
224  path = abspath(os.path.join(self['OutputDir'], name))
225  self._create_output_dir_create_output_dir(os.path.dirname(path), option)
226  return path
227 
228  def _process_output_name(self, option, name):
229  base, ext = os.path.splitext(name)
230  if self['TimestampOutputs']:
231  base = '%s-%s' % (base, self.start_timestampstart_timestamp)
232  ext = self._get_output_extension_get_output_extension(ext, option)
233  return base + ext
234 
235  def _get_output_extension(self, ext, type_):
236  if ext != '':
237  return ext
238  if type_ in ['Output', 'XUnit']:
239  return '.xml'
240  if type_ in ['Log', 'Report']:
241  return '.html'
242  if type_ == 'DebugFile':
243  return '.txt'
244  raise FrameworkError("Invalid output file type: %s" % type_)
245 
246  def _create_output_dir(self, path, type_):
247  try:
248  if not os.path.exists(path):
249  os.makedirs(path)
250  except EnvironmentError as err:
251  raise DataError("Creating %s file directory '%s' failed: %s"
252  % (type_.lower(), path, err.strerror))
253 
254  def _process_metadata_or_tagdoc(self, value):
255  if ':' in value:
256  return value.split(':', 1)
257  return value, ''
258 
259  def _process_report_background(self, colors):
260  if colors.count(':') not in [1, 2]:
261  raise DataError("Invalid report background colors '%s'." % colors)
262  colors = colors.split(':')
263  if len(colors) == 2:
264  return colors[0], colors[0], colors[1]
265  return tuple(colors)
266 
267  def _process_tag_stat_combine(self, pattern):
268  if ':' in pattern:
269  pattern, title = pattern.rsplit(':', 1)
270  else:
271  title = ''
272  return self._format_tag_patterns_format_tag_patterns(pattern), title
273 
274  def _format_tag_patterns(self, pattern):
275  for search, replace in [('&', 'AND'), ('AND', ' AND '), ('OR', ' OR '),
276  ('NOT', ' NOT '), ('_', ' ')]:
277  if search in pattern:
278  pattern = pattern.replace(search, replace)
279  while ' ' in pattern:
280  pattern = pattern.replace(' ', ' ')
281  if pattern.startswith(' NOT'):
282  pattern = pattern[1:]
283  return pattern
284 
285  def _process_tag_stat_link(self, value):
286  tokens = value.split(':')
287  if len(tokens) >= 3:
288  return tokens[0], ':'.join(tokens[1:-1]), tokens[-1]
289  raise DataError("Invalid format for option '--tagstatlink'. "
290  "Expected 'tag:link:title' but got '%s'." % value)
291 
293  value = self._convert_to_integer_convert_to_integer(name, value)
294  return value if value > 0 else self._get_default_value_get_default_value(name)
295 
296  def _convert_to_integer(self, name, value):
297  try:
298  return int(value)
299  except ValueError:
300  raise DataError("Option '--%s' expected integer value but got '%s'."
301  % (name.lower(), value))
302 
303  def _get_default_value(self, name):
304  return self._cli_opts_cli_opts_cli_opts[name][1]
305 
306  def _validate_remove_keywords(self, values):
307  for value in values:
308  try:
309  KeywordRemover(value)
310  except DataError as err:
311  raise DataError("Invalid value for option '--removekeywords'. %s" % err)
312 
313  def _validate_flatten_keywords(self, values):
314  try:
316  except DataError as err:
317  raise DataError("Invalid value for option '--flattenkeywords'. %s" % err)
318 
319  def __contains__(self, setting):
320  return setting in self._cli_opts_cli_opts_cli_opts
321 
322  def __unicode__(self):
323  return '\n'.join('%s: %s' % (name, self._opts_opts[name])
324  for name in sorted(self._opts_opts))
325 
326  @property
327  output_directory = property
328 
329  def output_directory(self):
330  return self['OutputDir']
331 
332  @property
333  output = property
334 
335  def output(self):
336  return self['Output']
337 
338  @property
339  log = property
340 
341  def log(self):
342  return self['Log']
343 
344  @property
345  report = property
346 
347  def report(self):
348  return self['Report']
349 
350  @property
351  xunit = property
352 
353  def xunit(self):
354  return self['XUnit']
355 
356  @property
357  log_level = property
358 
359  def log_level(self):
360  return self['LogLevel']
361 
362  @property
363  split_log = property
364 
365  def split_log(self):
366  return self['SplitLog']
367 
368  @property
369  status_rc = property
370 
371  def status_rc(self):
372  return self['StatusRC']
373 
374  @property
375  xunit_skip_noncritical = property
376 
378  return self['XUnitSkipNonCritical']
379 
380  @property
381  statistics_config = property
382 
383  def statistics_config(self):
384  return {
385  'suite_stat_level': self['SuiteStatLevel'],
386  'tag_stat_include': self['TagStatInclude'],
387  'tag_stat_exclude': self['TagStatExclude'],
388  'tag_stat_combine': self['TagStatCombine'],
389  'tag_stat_link': self['TagStatLink'],
390  'tag_doc': self['TagDoc'],
391  }
392 
393  @property
394  critical_tags = property
395 
396  def critical_tags(self):
397  return self['Critical']
398 
399  @property
400  non_critical_tags = property
401 
402  def non_critical_tags(self):
403  return self['NonCritical']
404 
405  @property
406  remove_keywords = property
407 
408  def remove_keywords(self):
409  return self['RemoveKeywords']
410 
411  @property
412  flatten_keywords = property
413 
414  def flatten_keywords(self):
415  return self['FlattenKeywords']
416 
417  @property
418  pre_rebot_modifiers = property
419 
421  return self['PreRebotModifiers']
422 
423  @property
424  console_colors = property
425 
426  def console_colors(self):
427  return self['ConsoleColors']
428 
429  @property
430  rpa = property
431 
432  def rpa(self):
433  return self['RPA']
434 
435  @rpa.setter
436 
437  def rpa(self, value):
438  self['RPA'] = value
439 
440 
442 
445  _extra_cli_opts = {'Extension' : ('extension', None),
446  'Output' : ('output', 'output.xml'),
447  'LogLevel' : ('loglevel', 'INFO'),
448  'MaxErrorLines' : ('maxerrorlines', 40),
449  'DryRun' : ('dryrun', False),
450  'ExitOnFailure' : ('exitonfailure', False),
451  'ExitOnError' : ('exitonerror', False),
452  'SkipTeardownOnExit' : ('skipteardownonexit', False),
453  'Randomize' : ('randomize', 'NONE'),
454  'RunEmptySuite' : ('runemptysuite', False),
455  'WarnOnSkipped' : ('warnonskippedfiles', None),
456  'Variables' : ('variable', []),
457  'VariableFiles' : ('variablefile', []),
458  'PreRunModifiers' : ('prerunmodifier', []),
459  'Listeners' : ('listener', []),
460  'ConsoleType' : ('console', 'verbose'),
461  'ConsoleTypeDotted' : ('dotted', False),
462  'ConsoleTypeQuiet' : ('quiet', False),
463  'ConsoleWidth' : ('consolewidth', 78),
464  'ConsoleMarkers' : ('consolemarkers', 'AUTO'),
465  'DebugFile' : ('debugfile', None)}
466 
468  settings = RebotSettings()
469  settings.start_timestamp = self.start_timestampstart_timestamp
470  settings._opts.update(self._opts_opts)
471  for name in ['Variables', 'VariableFiles', 'Listeners']:
472  del(settings._opts[name])
473  for name in ['Include', 'Exclude', 'TestNames', 'SuiteNames', 'Metadata']:
474  settings._opts[name] = []
475  for name in ['Name', 'Doc']:
476  settings._opts[name] = None
477  settings._opts['Output'] = None
478  settings._opts['LogLevel'] = 'TRACE'
479  settings._opts['ProcessEmptySuite'] = self['RunEmptySuite']
480  return settings
481 
482  def _output_disabled(self):
483  return self.outputoutputoutput is None
484 
485  def _escape_as_data(self, value):
486  return escape(value)
487 
488  @property
489  listeners = property
490 
491  def listeners(self):
492  return self['Listeners']
493 
494  @property
495  debug_file = property
496 
497  def debug_file(self):
498  return self['DebugFile']
499 
500  @property
501  suite_config = property
502 
503  def suite_config(self):
504  return {
505  'name': self['Name'],
506  'doc': self['Doc'],
507  'metadata': dict(self['Metadata']),
508  'set_tags': self['SetTag'],
509  'include_tags': self['Include'],
510  'exclude_tags': self['Exclude'],
511  'include_suites': self['SuiteNames'],
512  'include_tests': self['TestNames'],
513  'empty_suite_ok': self.run_empty_suiterun_empty_suiterun_empty_suite,
514  'randomize_suites': self.randomize_suitesrandomize_suitesrandomize_suites,
515  'randomize_tests': self.randomize_testsrandomize_testsrandomize_tests,
516  'randomize_seed': self.randomize_seedrandomize_seedrandomize_seed,
517  }
518 
519  @property
520  randomize_seed = property
521 
522  def randomize_seed(self):
523  return self['Randomize'][1]
524 
525  @property
526  randomize_suites = property
527 
528  def randomize_suites(self):
529  return self['Randomize'][0] in ('suites', 'all')
530 
531  @property
532  randomize_tests = property
533 
534  def randomize_tests(self):
535  return self['Randomize'][0] in ('tests', 'all')
536 
537  @property
538  dry_run = property
539 
540  def dry_run(self):
541  return self['DryRun']
542  @property
543  exit_on_failure = property
544 
545  def exit_on_failure(self):
546  return self['ExitOnFailure']
547 
548  @property
549  exit_on_error = property
550 
551  def exit_on_error(self):
552  return self['ExitOnError']
553 
554  @property
555  skip_teardown_on_exit = property
556 
558  return self['SkipTeardownOnExit']
559 
560  @property
561  console_output_config = property
562 
564  return {
565  'type': self.console_typeconsole_typeconsole_type,
566  'width': self.console_widthconsole_widthconsole_width,
567  'colors': self.console_colorsconsole_colorsconsole_colors,
568  'markers': self.console_markersconsole_markersconsole_markers,
569  'stdout': self['StdOut'],
570  'stderr': self['StdErr']
571  }
572 
573  @property
574  console_type = property
575 
576  def console_type(self):
577  if self['ConsoleTypeQuiet']:
578  return 'quiet'
579  if self['ConsoleTypeDotted']:
580  return 'dotted'
581  return self['ConsoleType']
582 
583  @property
584  console_width = property
585 
586  def console_width(self):
587  return self['ConsoleWidth']
588 
589  @property
590  console_markers = property
591 
592  def console_markers(self):
593  return self['ConsoleMarkers']
594 
595  @property
596  max_error_lines = property
597 
598  def max_error_lines(self):
599  return self['MaxErrorLines']
600 
601  @property
602  pre_run_modifiers = property
603 
604  def pre_run_modifiers(self):
605  return self['PreRunModifiers']
606 
607  @property
608  run_empty_suite = property
609 
610  def run_empty_suite(self):
611  return self['RunEmptySuite']
612 
613  @property
614  variables = property
615 
616  def variables(self):
617  return self['Variables']
618 
619  @property
620  variable_files = property
621 
622  def variable_files(self):
623  return self['VariableFiles']
624 
625  @property
626  extension = property
627 
628  def extension(self):
629  return self['Extension']
630 
631 
633 
636  _extra_cli_opts = {'Output' : ('output', None),
637  'LogLevel' : ('loglevel', 'TRACE'),
638  'ProcessEmptySuite' : ('processemptysuite', False),
639  'StartTime' : ('starttime', None),
640  'EndTime' : ('endtime', None),
641  'Merge' : ('merge', False)}
642 
643  def _output_disabled(self):
644  return False
645 
646  @property
647  suite_config = property
648 
649  def suite_config(self):
650  return {
651  'name': self['Name'],
652  'doc': self['Doc'],
653  'metadata': dict(self['Metadata']),
654  'set_tags': self['SetTag'],
655  'include_tags': self['Include'],
656  'exclude_tags': self['Exclude'],
657  'include_suites': self['SuiteNames'],
658  'include_tests': self['TestNames'],
659  'empty_suite_ok': self.process_empty_suiteprocess_empty_suiteprocess_empty_suite,
660  'remove_keywords': self.remove_keywordsremove_keywordsremove_keywords,
661  'log_level': self['LogLevel'],
662  'critical_tags': self.critical_tagscritical_tagscritical_tags,
663  'non_critical_tags': self.non_critical_tagsnon_critical_tagsnon_critical_tags,
664  'start_time': self['StartTime'],
665  'end_time': self['EndTime']
666  }
667 
668  @property
669  log_config = property
670 
671  def log_config(self):
672  if not self.logloglog:
673  return {}
674  return {
675  'rpa': self.rparparparpa,
676  'title': html_escape(self['LogTitle'] or ''),
677  'reportURL': self._url_from_path_url_from_path(self.logloglog, self.reportreportreport),
678  'splitLogBase': os.path.basename(os.path.splitext(self.logloglog)[0]),
679  'defaultLevel': self['VisibleLogLevel']
680  }
681 
682  @property
683  report_config = property
684 
685  def report_config(self):
686  if not self.reportreportreport:
687  return {}
688  return {
689  'rpa': self.rparparparpa,
690  'title': html_escape(self['ReportTitle'] or ''),
691  'logURL': self._url_from_path_url_from_path(self.reportreportreport, self.logloglog),
692  'background' : self._resolve_background_colors_resolve_background_colors(),
693  }
694 
695  def _url_from_path(self, source, destination):
696  if not destination:
697  return None
698  return get_link_path(destination, os.path.dirname(source))
699 
701  colors = self['ReportBackground']
702  return {'pass': colors[0], 'nonCriticalFail': colors[1], 'fail': colors[2]}
703 
704  @property
705  merge = property
706 
707  def merge(self):
708  return self['Merge']
709 
710  @property
711  console_output_config = property
712 
714  return {
715  'colors': self.console_colorsconsole_colorsconsole_colors,
716  'stdout': self['StdOut'],
717  'stderr': self['StdErr']
718  }
719 
720  @property
721  process_empty_suite = property
722 
724  return self['ProcessEmptySuite']
def _url_from_path(self, source, destination)
Definition: settings.py:695
def _get_output_file(self, option)
Returns path of the requested output file and creates needed dirs.
Definition: settings.py:215
def _convert_to_integer(self, name, value)
Definition: settings.py:296
def _convert_to_positive_integer_or_default(self, name, value)
Definition: settings.py:292
def _raise_invalid_option_value(self, option_name, given_value)
Definition: settings.py:198
def _validate_log_level_and_default(self, log_level, default)
Definition: settings.py:164
def _process_output_name(self, option, name)
Definition: settings.py:228
def __init__(self, options=None, **extra_options)
Definition: settings.py:80
Used when variable does not exist.
Definition: errors.py:67
Can be used when the core framework goes to unexpected state.
Definition: errors.py:59
def html_escape(text, linkify=True)
Definition: markuputils.py:40
def abspath(path, case_normalize=False)
Replacement for os.path.abspath with some enhancements and bug fixes.
Definition: robotpath.py:87
def get_link_path(target, base)
Returns a relative path to target from base.
Definition: robotpath.py:100
def format_time(timetuple_or_epochsecs, daysep='', daytimesep=' ', timesep=':', millissep=None)
Returns a timestamp formatted from given time using separators.
Definition: robottime.py:183
def split_args_from_name_or_path(name)
Definition: text.py:132