Metadata-Version: 2.1
Name: fstringen
Version: 0.0.7
Summary: A text generator based on f-strings
Home-page: https://github.com/alnvdl/fstringen
Author: Allan Vidal
License: UNKNOWN
Description: # fstringen
        fstringen (pronounced: f-string-gen) is a library for writing text and code
        generators in Python. It builds upon [f-strings](
        https://docs.python.org/3/reference/lexical_analysis.html#f-strings) available
        in Python 3.6+, and it is based on two core concepts: models and generators.
        
        fstringen was designed to generate code based on OpenAPI specs, but that's
        just one possible use case. It can take any dictionary-equivalent model
        (including YAML and JSON) and turn that into a browsable model, with
        rudimentary support for cross-references. Generators then transform this model
        in the desired output.
        
        A `Selectable` is simply a Python dictionary (which may be sourced from a YAML
        or JSON file) representing a hierarchy, typically with deep nesting. The
        `select` operation is run on `Selectable`s to select a new `Selectable` based
        on a path selection mechanism. `Model` is just an alias for `Selectable`, and
        it's usually used when referring to a `Selectable` loaded from a file
        
        Generators are functions annotated with the `@gen()` decorator, which gives
        some extra powers to special f-strings expressions in them (automagic
        indentation, smart list insertion and scope-related hacks). Generators may also
        be configured to automatically output to files, with optional header notices.
        
        ## Installing
        You can install directly from PyPI:
        
            $ pip3 install fstringen --user
        
        ## Using
        fstringen is based on special f-strings, called fstringstars. They are
        basically triple-quoted f-strings that start and ends with an asterisk (`*`).
        This special syntax indicates to fstringen that the string should be adapted
        with extra features like automagic indentation, smart list insertion and
        scope-escaping tricks.
        
        A generator that outputs to a file looks like this (this is the `example.py`
        file in this project):
        
        ```py
        from fstringen import gen, Model
        
        model = Model.fromDict({
            "structs": {
                "mystruct": {
                    "color": "string"
                },
                "anotherstruct": {
                    "name": "string",
                    "age": "int"
                }
            }
        })
        
        
        @gen()
        def gen_struct(struct):
            fields = ["{} {}".format(field.name, field)
                      for field in struct.select("*")]
        
            return f"""*
            type {struct.name} struct {{
                {fields}
            }}
        
            *"""
        
        
        @gen(model=model, fname="myfile.go", comment="//")
        def gen_myfile(model):
            return f"""*
            package main
        
            // Let's generate some structs!
            {[gen_struct(struct) for struct in model.select("/structs/*")]}
            *"""
        ```
        
        All generator functions using fstringstars must be decorated with `@gen()`.
        When no parameters are given, the generator is considerate a subordinate
        generator (i.e., they need to be called explicitly from other generators).
        When the `model` and `fname` arguments are used, the generator becomes a file
        generator, which is automatically executed and output to that file when the
        script exists (i.e., you don't need to explicitly call file generators).
        
        Inside generators, fstringstars can use regular f-string `{expression}`
        invocations.
        
        The real power of fstringen comes with `Selectable`s and `Model`s, which allow
        easy selection of data (`Model` is just an alias for `Selectable`, and `Model`
        is usually used when referring to a `Selectable` loaded from a file):
        
        - Every `Selectable` has the `select` method, which takes a `path` and returns
          a new `Selectable` based on the query that path indicates.
        - Every `Selectable` has a `name` attribute, corresponding to the dictionary
          key or array index for that element.
        - If a path ends with `/*` and the preceding path contains a dictionary,
          a `Selectable` list of `Selectable`s is returned, containing all items in
          that dictionary.
        - If a path element ends with `->`, the value contained in that attribute is
          assumed to contain a path (absolute or relative), and that path is used to
          look up the referenced object in the same `Model`.
        - Three convenience methods are also available in `Selectable`s. All of them
          can take a path to query under that `Selectable`, of if called without a
          path, they apply to the `Selectable` in question:
          - `is_reference` checks whether a given `Selectable` contains a reference.
          - `has` allows for verification of the existence of a path under that
            `Selectable`.
          - `is_enabled` method verifies that the path exists and has a truthy value.
        
        The two main imports from `fstringen` are `gen` and `Model`. An additional
        import is available, `Mapper`, but it's entirely optional. It wraps a
        dictionary for looking up things like type mappings, and it returns alarming
        strings when no match is found.
        
        ## Caveats
        fstringen does dangerous things with scope and function re-declaration. This
        means you should only use it in scripts that are code generators, and code
        generators alone (i.e., they don't do anything else). We sacrificed correctness
        for neatness and ease-to-use.
        
        Python 3.6+ is required. PyYAML is an optional dependency.
        
        ## Known issues
        Because of Python limitations, a few things are not possible:
        
        **Quotes in fstringstars strings**
        
        Just as you can't have a triple-quoted string like this in Python:
        
            my_str = """"a""""
        
        You can't have a fstringstar like this:
        
            my_fstringsar = f"""*"a"*"""
        
        That's because Python can't figure out how that string starts or ends
        (fstringstars are compiled to triple-quoted Python f-strings). You achieve the
        same result in two different ways. Using line breaks:
        
            my_fstringsar = f"""*
            "a"
            *"""
        
        Or with escapes in a single-line:
        
            my_fstringsar = f"""*\\\"a\\\"*"""
        
        
        **Don't compare with `is` and avoid `isinstance`**
        When dealing with a `Selectable` or a `Model`, don't use the `is` comparison
        operator. Consider the following code:
        
            mybool = model.select("/path/to/a/bool")
        
        When checking whether `mybool` is `True` or `False`, do it using `==` or if in
        a conditional, just check the value directly without a comparison
        (`if mybool`). The same applies to `None`.
        
        The reason for this limitation is that `select` always returns a `Selectable`,
        and a `Selectable` can never be compared to Python objects using the `is`
        operator, which verifies that two expressions point to the same object.
        However, equality operators (`==` and `!=`) work just fine because `Selectable`
        applies some magic.
        
        Because `NoneType` and `bool` cannot be subclassed in Python, a `Selectable`
        isn't able to inherit from those (as it does for `int`, `str`, `list`, `dict`,
        etc.). For that reason, you should also avoid using `isinstance`. Instead, you
        can verify the original type for a value by checking the `type` attribute in a
        `Selectable`.
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Code Generators
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.6
Description-Content-Type: text/markdown
