Exemple #1
0
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
Exemple #2
0
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, ")"))
Exemple #3
0
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)
Exemple #4
0
    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()))
Exemple #5
0
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)
Exemple #7
0
 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
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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')
Exemple #14
0
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
Exemple #15
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
Exemple #16
0
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))
Exemple #17
0
 def open_file(wpath):
     serr.write(f"MARKDOWN FILE: {wpath}\n")
     from contextlib import nullcontext as func
     return func(write)
Exemple #18
0
 def open_file(wpath):
     from contextlib import nullcontext as func
     return func(write)
Exemple #19
0
 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)
Exemple #21
0
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)
Exemple #22
0
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)
Exemple #24
0
 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
Exemple #26
0
def _read_only_business_collection(collection_path):
    from pho import read_only_business_collection_via_path_ as func
    return func(collection_path)
Exemple #27
0
def _foz_via(defs, pner, x=None):
    from script_lib.cheap_arg_parse import formals_via_definitions as func
    return func(defs, pner, x)
Exemple #28
0
def pass_thru_cm(x):
    from contextlib import nullcontext as func
    return func(x)