def _parse_SSG_adapter_name(sout, serr, arg, pname): import re mod, extra = None, None if re.match(r'^[A-Za-z_-]+\Z', arg): if 'help' == arg: _ = _oxford_join(_SSG_adapter_names(), ' and ') serr.write(f"Available SSG adapters: {_}\n") return None, 0 if 'list' == arg: for slug in _SSG_adapter_names(): sout.write(slug) sout.write('\n') return None, 0 use = arg.replace('-', '_') from importlib import import_module as func try: mod = func(f"pho.SSG_adapters_.{use}") except ModuleNotFoundError as e: extra = e.msg if mod is None: _ = _oxford_join(_SSG_adapter_names(), ' or ') serr.write(f"No SSG adapter {arg!r}. Available: {_}\n") if extra: serr.write(''.join(('(', extra, ')\n'))) serr.write(f"See '{pname} -h' for help\n") return None, 123 return mod, None
def _splay_memory(neg_mem): max_displayed = 2 # the number of features you display can meet not exceed num_displayed = 0 # keep track of how many *unique* features you've seen max_exceeded = False # is there at least one more than the max seen, display = {}, [] for feat_x in neg_mem: if seen.get(feat_x, False): continue if max_displayed == num_displayed: max_exceeded = True break seen[feat_x] = True num_displayed += 1 display.append(feat_x) say = placeholder_for_say_subfeature these = (say(o) for o in display) from text_lib.magnetics.via_words import oxford_join, ELLIPSIS_JOIN func = ELLIPSIS_JOIN if max_exceeded else oxford_join this_and_this = func(these) return ''.join(("(there's ", this_and_this, ")"))
def _build_end_state(fh, listener, emissions, num_emis): typ, mixed = fh if 'file_not_lines' == typ: path = fixture_path(mixed) # entry opened = open(path) else: assert 'lines_not_file' == typ from contextlib import nullcontext as func opened = func(mixed) # iterator single_table_doc_scn_via_lines = subject_function() with opened as lines: dscn = single_table_doc_scn_via_lines(lines, listener) lines1 = tuple(dscn.release_leading_non_table_lines()) sch = dscn.ok and dscn.release_complete_schema() asts = dscn.ok and tuple(dscn.release_business_row_ASTs()) lines2 = dscn.ok and tuple(dscn.release_trailing_non_table_lines()) msgs = None if 0 != num_emis: assert 1 == num_emis emi, = emissions msgs = tuple(emi.to_messages()) return _EndState(did_succeed=dscn.ok, error_messages=msgs, leading_non_table_lines=lines1, complete_schema=sch, business_row_ASTs=asts, trailing_non_table_lines=lines2)
def open_two_via_items(items): def these(): for k, v in items: yield _MinimalEntity(k, v) from contextlib import nullcontext as func return func((None, these()))
def key_and_entity_via_collection( collection, needle_function, listener, item_noun_phrase=None, do_splay=True, subfeatures_via_item=_subfeatures_via_item_default_function, channel_tail_component_on_not_found=None, say_needle=None, say_collection=None, ): """ given the request, resolve exactly one item from the collection or None. when one item can be resolved, it is returned as a tuple alongside its natural key (as `(natural_key, item)`). essential function of [#874.2] collection API. currently an ad-hoc spike. """ ui_tup = (channel_tail_component_on_not_found, say_needle, item_noun_phrase, say_collection, listener) # #here1 func = _procure_when_splay if do_splay else _procure_when_no_splay return func(collection, needle_function, subfeatures_via_item, ui_tup)
def produce_opened(): if do_edit_in_place: # Open the file as 'r+' (not 'w') to ensure it exists first return wpath, open(wpath, 'r+') # #here1 assert do_preview from contextlib import nullcontext as func return f"«stdout» (not {wpath})", func(self.stdout)
def fixture_lines_or_file(self): func = self.given_markdown_lines if func: return 'lines_not_file', func() path = self.given_markdown() # == BEGIN some legacy-ism from before #history-B.4 idk assert isinstance(path, str) assert '\n' not in path return 'file_not_lines', path
def _read_only_business_collection_via_fixture_path(fpath): i = fpath.rindex('.') head = fpath[:i] tail = fpath[i + 1:] from importlib import import_module as func mod = func(head) cls = getattr(mod, tail) tc = cls(methodName='CAN_BE_USED_BY_VISUAL_TEST') return tc.COLLECTION_FOR_VISUAL_TEST
def _crazy_parse(arg_func): from modality_agnostic.magnetics.formal_parameter_via_definition \ import parameter_index_via_mixed as func # (pi = parameter index) pi = func(arg_func, do_crazy_hack=True) assert not pi.parameters_that_start_with_underscores # or _listener, _coll pool = { k: param for k, param in pi.parameters_that_do_not_start_with_underscores } return pool, pi.desc_lines
def _SSG_adapter_names(): from os.path import splitext, basename, dirname as dn, join package_path = dn(dn(dn(__file__))) here = join(package_path, 'SSG_adapters_') glob_path = join(here, '[a-z]*') from glob import glob as func these = func(glob_path) def clean(s): bn = basename(s) head, _ = splitext(bn) return head.replace('_', '-') return tuple(sorted(clean(s) for s in these)) # sort, not up to FS
def fake_producer_script_via_dictionary_tuple(dct_tup): # covered here class fake_producer_script: # #class-as-namespace # [#459.17] producer script fake modules (see nearby other) def multi_depth_value_dictionary_stream_via_traversal_stream(dcts): return dcts def open_traversal_stream(listener): from contextlib import nullcontext as func return func(dct_tup) fake_producer_script.__file__ = __file__ import data_pipes.format_adapters.producer_script as sa_mod from kiss_rdb import collection_via_storage_adapter_and_path as func return func(sa_mod, fake_producer_script, None)
def fake_STDOUT_and_lines_for(tc): lines = [] if tc.do_debug: def recv_write(line): stderr.write(f'DEBUG STDOUT: {line}') lines.append(line) from sys import stderr stderr.write('\n') # meh else: recv_write = lines.append from modality_agnostic import write_only_IO_proxy as func return func(recv_write, on_OK_exit=lambda: None), lines
def listener(*args): write = self.stderr.write mood, shape, typ, *rest, payloader = args if 'expression' == shape: for line in payloader(): write(f'{line}\n') assert 'structure' == shape dct = payloader() chan_tail = (typ, *rest) from script_lib.magnetics.expression_via_structured_emission \ import func itr = func(chan_tail, dct) for line in itr: write(line) if '\n' != line[-1]: write('\n')
def _CLI_for_tree(sin, sout, serr, bash_argv, efx=None): """Generate an ASCII visualization of the collection inspired by the `tree` unix utility """ tup, rc = _common_start(sout, serr, bash_argv, efx, _CLI_for_tree, _formals_for_tree) if tup is None: return rc coll_path, vals, foz, mon = tup big_index = _big_index_via(coll_path, mon.listener, vals.get('NCID'), vals.get('test')) if big_index is None: return mon.returncode from pho.notecards_.graph_via_collection import \ tree_ASCII_art_lines_via as func for line in func(big_index): sout.write(line) return 0
def _CLI_for_dotfile(sin, sout, serr, bash_argv, efx=None): """Generate a graph-viz document from a notecards collection Show every relationship between every notecard in the collection. Output a graph-viz digraph of the whole collection. """ tup, rc = _common_start(sout, serr, bash_argv, efx, _CLI_for_dotfile, _formals_for_dotfile) if tup is None: return rc coll_path, vals, foz, mon = tup big_index = _big_index_via(coll_path, mon.listener, vals.get('NCID'), vals.get('test')) if big_index is None: return mon.returncode from pho.notecards_.graph_via_collection import \ graphviz_dotfile_lines_via_ as func for line in func(big_index, mon.listener): sout.write(line) return mon.returncode
def lines_via_indendted_big_string(big_string): from re import finditer as func # [#610] return (md[1] for md in func(r'^[ ]*((?:[^ ][^\n])*?\n)', big_string))
def open_file(wpath): serr.write(f"MARKDOWN FILE: {wpath}\n") from contextlib import nullcontext as func return func(write)
def open_file(wpath): from contextlib import nullcontext as func return func(write)
def open_schema_and_entity_trav(listener): from contextlib import nullcontext as func # we don't close stdin return func((None, entities()))
def _make_project_directory(make_project): from os import mkdir mkdir(make_project) from contextlib import nullcontext as func return func(make_project)
def _normal_lines_via_docstring(big_string): from modality_agnostic.magnetics.formal_parameter_via_definition \ import normal_lines_via_docstring as func return func(big_string)
def _oxford_join(slugs, sep): from pho.magnetics_.text_via import oxford_join as func return func(slugs, sep)
def open_traversal_stream(listener): from contextlib import nullcontext as func return func(dct_tup)
def lines(line_width): from pho.magnetics_.text_via import \ word_wrap_pieces_using_commas as func return func(pieces_without_commas(), line_width)
def execute__generate__(self): # also called by client at #history-B.4 stack = self._arg_stack do_usage, do_help, do_invite, returncode = False, False, False, None flag_formals_and_actuals = { '-i': False, '--preview': False, } formal_positionals_stack = ['COLLECTION_PATH'] actual_positionals = [] while len(stack): arg = stack.pop() if '-' == arg[0]: if _looks_like_help_flag(arg): do_help, returncode = True, 0 break if arg in flag_formals_and_actuals: flag_formals_and_actuals[arg] = True continue self.stderr.write(f"unrecognized option {repr(arg)}\n") do_usage, do_invite, returncode = True, True, 124 break if len(formal_positionals_stack): formal_positionals_stack.pop() actual_positionals.append(arg) continue self.stderr.write(f"unexpected argument: {arg!r}\n") do_usage, do_invite, returncode = True, True, 125 break if returncode is None and len(formal_positionals_stack): which = formal_positionals_stack[-1] self.stderr.write(f"expecting {which}\n") do_invite, returncode = True, 126 if returncode is None: do_preview = flag_formals_and_actuals.pop('--preview') do_edit_in_place = flag_formals_and_actuals.pop('-i') assert not flag_formals_and_actuals coll_path, = actual_positionals if do_edit_in_place: if do_preview: self.stderr.write( "'-i' and '--preview' are mutually exclusive\n" ) # noqa: E501 do_invite, returncode = True, 127 elif not do_preview: self.stderr.write("Must have one of '-i' or '--preview'\n") do_invite, returncode = True, 128 def say_pn(): return f"{self.program_name} generate" if do_usage: self.stderr.write(f"usage: {say_pn()} {{COLLECTION_PATH}}\n") if do_help: self.stderr.write( "description: output to STDOUT the should-be lines of an index file\n" ) # noqa: E501 if do_invite: self.stderr.write(f"use '{say_pn()} -h' for help\n") if returncode is not None: return returncode # having done all the above, cheap_arg_parse might be in order listener = self.build_listener() # coll_path = self.os_path.abspath(coll_path) # resolve collection from kiss_rdb import collectionerer coll = collectionerer().collection_via_path(coll_path, listener) if coll is None: return 123 def produce_opened(): if do_edit_in_place: # Open the file as 'r+' (not 'w') to ensure it exists first return wpath, open(wpath, 'r+') # #here1 assert do_preview from contextlib import nullcontext as func return f"«stdout» (not {wpath})", func(self.stdout) from .identifiers_via_index import \ index_file_path_via_collection_path_ as func wpath = func(coll_path) depth = coll.custom_functions.number_of_digits_ with coll.open_identifier_traversal(listener) as idens: lines = _lines_of_index_via_identifiers(idens, depth, listener) desc_and_fh = produce_opened() if desc_and_fh is None: return 124 desc, wopened = desc_and_fh bytes_tot = 0 with wopened as out_filehandle: write = out_filehandle.write for line in lines: bytes_tot += write(line) out_filehandle.truncate() # #here1 # (if the new file size is smaller than previous. ok on stdout) self.stderr.write(f"(wrote {bytes_tot} bytes to {desc})\n") return 0
def _read_only_business_collection(collection_path): from pho import read_only_business_collection_via_path_ as func return func(collection_path)
def _foz_via(defs, pner, x=None): from script_lib.cheap_arg_parse import formals_via_definitions as func return func(defs, pner, x)
def pass_thru_cm(x): from contextlib import nullcontext as func return func(x)