def __init__(self, **kwargs): """ Validates configuration parameter types and values. """ # Load default values. self.conf = self.default_conf.copy() unrecognized_options = set(kwargs) - set(self.default_conf) if unrecognized_options: raise ValueError(f"Unrecognized {unrecognized_options} options.") # Replace defaults values with our config. self.conf.update(kwargs) # Check thresholds. assert self.size_threshold >= -1 assert self.content_threshold >= -1 # Headers are case-insensitive in Python implementation. normalized_headers = [h.lower() for h in self.hash_headers] # Remove duplicate entries. normalized_headers = unique(normalized_headers) # Mail headers are composed of ASCII characters between 33 and 126 # (both inclusive) according the RFC-5322. for hid in normalized_headers: ascii_indexes = set(map(ord, hid)) assert max(ascii_indexes) <= 126 assert min(ascii_indexes) >= 33 self.hash_headers = tuple(normalized_headers) # Export mail box will always be created from scratch and is not # expected to exists in the first place. if self.export: self.export = Path(self.export).resolve() if self.export.exists(): raise FileExistsError(self.export)
def from_parse(cls, cmd_flag_map, flag_name): # TODO: add edit distance calculation valid_flags = unique([format_flag_label(flag) for flag in cmd_flag_map.values() if not flag.display.hidden]) msg = ('unknown flag "%s", choose from: %s' % (flag_name, ', '.join(valid_flags))) return cls(msg)
def _fmt_conda_cmd(pkgs=None, files=None, offline=False, update_deps=True, channel_priority=False): if not (pkgs or files): return ": # no-op conda install" if pkgs and files: raise ValueError("expected pkgs or files, not both: %r, %r" % (pkgs, files)) pkgs = list(pkgs or []) files = list(files or []) cmd = ('/home/app/miniconda2/bin/conda install' ' -y -q --show-channel-urls ') if offline: cmd += '--offline ' if not channel_priority: cmd += '--no-channel-priority ' if not update_deps: cmd += '--no-update-dependencies ' channels = ['defaults'] + [pkg.channel for pkg in pkgs] if files: cmd += ' ' + ' '.join(files) if pkgs: # autodisables MKL in favor of openblas since it is ~600MB cmd += ' '.join( ['--channel %s' % chan for chan in iterutils.unique(channels)] + ['nomkl'] + [pkg.pkg + '==' + pkg.ver for pkg in pkgs]) return cmd
def format_nonexp_repr(obj, req_names=None, opt_names=None, opt_key=None): """Format a non-expression-style repr Some object reprs look like object instantiation, e.g., App(r=[], mw=[]). This makes sense for smaller, lower-level objects whose state roundtrips. But a lot of objects contain values that don't roundtrip, like types and functions. For those objects, there is the non-expression style repr, which mimic's Python's default style to make a repr like this: <Flag name='abc' parse_as=<type 'int'>> """ cn = obj.__class__.__name__ req_names = req_names or [] opt_names = opt_names or [] all_names = unique(req_names + opt_names) if opt_key is None: opt_key = lambda v: v is None assert callable(opt_key) items = [(name, getattr(obj, name, None)) for name in all_names] labels = ['%s=%r' % (name, val) for name, val in items if not (name in opt_names and opt_key(val))] if not labels: labels = ['id=%s' % id(obj)] ret = '<%s %s>' % (cn, ' '.join(labels)) return ret
def template_count(pta, template_name=None, template_names=None, template_regex=None, case_sensitive=False): article_tmpl_names = pta.templates if template_name: if template_names: raise RuntimeError( 'template_count metric expected one of' ' "template_name" or "template_names" arg, not both') template_names = [template_name] if not template_names: return len(article_tmpl_names) if not case_sensitive: article_tmpl_names = unique([t.lower() for t in article_tmpl_names]) template_names = unique([tn.lower() for tn in template_names]) if template_regex: template_pattern = re.compile(template_regex) return len( [t for t in article_tmpl_names if re.search(template_pattern, t)]) return len(set(template_names) & set(article_tmpl_names))
def format_exp_repr(obj, pos_names, req_names=None, opt_names=None, opt_key=None): cn = obj.__class__.__name__ req_names = req_names or [] opt_names = opt_names or [] all_names = unique(req_names + opt_names) if opt_key is None: opt_key = lambda v: v is None assert callable(opt_key) args = [getattr(obj, name, None) for name in pos_names] kw_items = [(name, getattr(obj, name, None)) for name in all_names] kw_items = [(name, val) for name, val in kw_items if not (name in opt_names and opt_key(val))] return format_invocation(cn, args, kw_items)
def perform_action(dedup): """Performs the action on selected mail candidates.""" logger.info(f"Perform {choice_style(dedup.conf.action)} action...") selection_count = len(dedup.selection) if selection_count == 0: logger.warning("No mail selected to perform action on.") return logger.info(f"{selection_count} mails selected for action.") # Check our indexing and selection methods are not flagging candidates # several times. assert len(unique(dedup.selection)) == len(dedup.selection) assert len(dedup.selection) == dedup.stats["mail_selected"] # Hunt down for action implementation. method = ACTIONS.get(dedup.conf.action) if not method: raise NotImplementedError( f"{dedup.conf.action} action not implemented yet.") method(dedup)
def __init__(self, project_list, tagsonomy): self.project_list = [] self.tagsonomy = tagsonomy self.tag_registry = OMD() for tag_group in ('topic', 'platform'): # TODO: framework, license for tag in self.tagsonomy[tag_group]: self.register_tag(tag_group, tag) errors = [] for project in project_list: new_tags = tuple( soft_sorted(project.get('tags', []), first=self.tag_registry.keys())) project['tags'] = new_tags try: project_obj = Project.from_dict(project) except ApatiteError as ae: errors.append(ae) continue self.project_list.append(project_obj) dupe_groups = redundant(self.project_list, key=lambda p: slugify(p.name), groups=True) dupe_groups += redundant(self.project_list, key=lambda p: p.repo_url, groups=True) dupe_groups = unique([tuple(dg) for dg in dupe_groups]) for group in dupe_groups: dpe = DuplicateProjectError('ambiguous or duplicate projects: %r' % [p.name for p in group]) errors.append(dpe) if errors: raise ProjectListError.from_errors(errors) return
def get_flags(self, path=(), with_hidden=True): flag_map = self.get_flag_map(path=path, with_hidden=with_hidden) return unique(flag_map.values())
def from_parse(cls, prs, subcmd_name): # TODO: add edit distance calculation valid_subcmds = unique([path[:1][0] for path in prs.subprs_map.keys()]) msg = ('unknown subcommand "%s", choose from: %s' % (subcmd_name, ', '.join(valid_subcmds))) return cls(msg)
def in_wikiproject(pta, wikiproject=None, case_sensitive=False): wikiprojects = pta.wikiprojects if not case_sensitive: wikiprojects = unique([w.lower() for w in wikiprojects]) wikiproject = wikiproject.lower() return wikiproject in wikiprojects
def get_help_text(self, parser, subcmds=(), program_name=None): """Turn a :class:`Parser` or :class:`Command` into a multiline formatted help string, suitable for printing. Includes the usage line and trailing newline by default. Args: parser (Parser): A :class:`Parser` or :class:`Command` object to generate help text for. subcmds (tuple): A sequence of subcommand strings specifying the subcommand to generate help text for. Defaults to ``()``. program_name (str): The program name, if it differs from the default ``sys.argv[0]``. (For example, ``example.py``, when running the command ``python example.py --flag val arg``.) """ # TODO: incorporate "Arguments" section if posargs has a doc set ctx = self.ctx ret = [ self.get_usage_line(parser, subcmds=subcmds, program_name=program_name) ] append = ret.append append(ctx['group_break']) shown_flags = parser.get_flags(path=subcmds, with_hidden=False) if subcmds: parser = parser.subprs_map[subcmds] if parser.doc: append( _wrap_stout_cmd_doc( indent=ctx['section_indent'], doc=parser.doc, max_width=ctx['width'] or get_wrap_width(max_width=ctx['max_width']))) append(ctx['section_break']) if parser.subprs_map: subcmd_names = unique([sp[0] for sp in parser.subprs_map if sp]) subcmd_layout = self._get_layout(labels=subcmd_names) append(ctx['subcmd_section_heading']) append(ctx['group_break']) for sub_name in unique([sp[0] for sp in parser.subprs_map if sp]): subprs = parser.subprs_map[(sub_name, )] # TODO: sub_name.replace('_', '-') = _cmd -> -cmd (need to skip replacing leading underscores) subcmd_lines = _wrap_stout_pair( indent=ctx['section_indent'], label=sub_name.replace('_', '-'), sep=ctx['doc_separator'], doc=subprs.doc, doc_start=subcmd_layout['doc_start'], max_doc_width=subcmd_layout['doc_width']) ret.extend(subcmd_lines) append(ctx['section_break']) if not shown_flags: return '\n'.join(ret) fmt_flag_label = ctx['format_flag_label'] flag_labels = [fmt_flag_label(flag) for flag in shown_flags] flag_layout = self._get_layout(labels=flag_labels) fmt_flag_post_doc = ctx['format_flag_post_doc'] append(ctx['flags_section_heading']) append(ctx['group_break']) for flag in shown_flags: disp = flag.display if disp.full_doc is not None: doc = disp.full_doc else: _parts = [disp.doc] if disp.doc else [] post_doc = disp.post_doc if disp.post_doc else fmt_flag_post_doc( flag) if post_doc: _parts.append(post_doc) doc = ' '.join(_parts) flag_lines = _wrap_stout_pair( indent=ctx['section_indent'], label=fmt_flag_label(flag), sep=ctx['doc_separator'], doc=doc, doc_start=flag_layout['doc_start'], max_doc_width=flag_layout['doc_width']) ret.extend(flag_lines) return ctx['pre_doc'] + '\n'.join(ret) + ctx['post_doc']