Skip to main content

Boilerplate Generator for Classes

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

PrefabClasses - Python Class Boilerplate Generator

PrefabClasses Test Status

Writes the class boilerplate code so you don't have to. Yet another variation on attrs/dataclasses.

Unlike dataclasses or attrs, prefab_classes has a focus on performance and startup time in particular. This includes trying to minimise the impact of importing the module itself.

Classes are written lazily when you first access the methods or eagerly when the module is compiled into a .pyc or rewritten out to a new .py source file.

The dynamic method of evaluating lazily is more flexible, while the compiled method is faster (once the .pyc file has been generated).

For more detail look at the documentation.

Usage

Define the class using plain assignment and attribute function calls:

from prefab_classes import prefab, attribute

@prefab
class Settings:
    hostname = attribute(default="localhost")
    template_folder = attribute(default='base/path')
    template_name = attribute(default='index')

Or with type hinting:

from prefab_classes import prefab

@prefab
class Settings:
    hostname: str = "localhost"
    template_folder: str = 'base/path'
    template_name: str = 'index'

In either case the result behaves the same.

>>> from prefab_classes.funcs import to_json
>>> s = Settings()
>>> print(s)
Settings(hostname='localhost', template_folder='base/path', template_name='index')
>>> to_json(s)
'{"hostname": "localhost", "template_folder": "base/path", "template_name": "index"}'

For further details see the usage pages in the documentation.

Why not just use attrs/dataclasses?

If attrs or dataclasses solves your problem then you should use them. They are thoroughly tested, well supported packages. This is a new project and has not had the rigorous real world testing of either of those.

Dataclasses/attrs/pydantic all impose some overhead on startup time. Prefab classes aims to minimise startup time and performance impact of class generation and in doing so sacrifices some features or nice internals of these other implementations.

Import time example:

Command Mean [ms] Min [ms] Max [ms] Relative
python -c "pass" 26.6 ± 1.2 25.0 30.6 1.00
python -c "import prefab_classes" 28.4 ± 0.4 27.6 29.5 1.07 ± 0.05
python -c "import dataclasses" 48.4 ± 1.0 46.5 51.5 1.82 ± 0.09
python -c "import attrs" 67.3 ± 0.7 65.9 71.1 2.53 ± 0.11
python -c "import pydantic" 105.4 ± 3.4 100.3 115.7 3.96 ± 0.22

For more detailed tests you can look at the performance section of the docs.

How does it work

The @prefab decorator either rewrites the class dynamically, putting methods in place that will be generated as they are first accessed OR it acts as a marker to indicate the class should be transformed for the compiled classes.

Compiled classes can both be imported directly or converted back to new .py files. Direct import will perform the conversion before creating the .pyc file.

example.py

# COMPILE_PREFABS
from prefab_classes import prefab, attribute
from pathlib import Path


@prefab(compile_prefab=True)
class SettingsPath:
    hostname = attribute(default="localhost")
    template_folder = attribute(default='base/path')
    template_name = attribute(default='index')
    file_types = attribute(default_factory=list)

    def __prefab_post_init__(self, template_folder, file_types):
        self.template_folder = Path(template_folder)
        file_types.extend(['.md', '.html'])
        self.file_types = file_types

Direct import using prefab_compiler

from prefab_classes import prefab_compiler

with prefab_compiler():
    from example import SettingsPath

# Use normally from here

Compile to a new .py file using rewrite_to_py:

>>> from prefab_classes.compiled import rewrite_to_py
>>> rewrite_to_py('example.py', 'example_compiled.py', use_black=True)

Using black to format for ease of reading.

example_compiled.py

# DO NOT MANUALLY EDIT THIS FILE
# MODULE: example_compiled.py
# GENERATED FROM: example.py
# USING prefab_classes VERSION: v0.9.1

from pathlib import Path


class SettingsPath:
    COMPILED = True
    PREFAB_FIELDS = ["hostname", "template_folder", "template_name", "file_types"]
    __match_args__ = ("hostname", "template_folder", "template_name", "file_types")

    def __init__(
        self,
        hostname="localhost",
        template_folder="base/path",
        template_name="index",
        file_types=None,
    ):
        self.hostname = hostname
        self.template_name = template_name
        file_types = file_types if file_types is not None else list()
        self.__prefab_post_init__(
            template_folder=template_folder, file_types=file_types
        )

    def __repr__(self):
        return f"{type(self).__qualname__}(hostname={self.hostname!r}, template_folder={self.template_folder!r}, template_name={self.template_name!r}, file_types={self.file_types!r})"

    def __eq__(self, other):
        return (
            (self.hostname, self.template_folder, self.template_name, self.file_types)
            == (
                other.hostname,
                other.template_folder,
                other.template_name,
                other.file_types,
            )
            if self.__class__ == other.__class__
            else NotImplemented
        )

    def __prefab_post_init__(self, template_folder, file_types):
        self.template_folder = Path(template_folder)
        file_types.extend([".md", ".html"])
        self.file_types = file_types

If compile_plain=True is provided as an argument to @prefab the COMPILED and PREFAB_FIELD variables will not be set on the class.

Credit

autogen function and some magic method definitions taken from David Beazley's Cluegen

General design based on previous experience using dataclasses and attrs and trying to match the requirements for PEP 681.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

prefab_classes-0.10.1.tar.gz (67.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

prefab_classes-0.10.1-py3-none-any.whl (39.6 kB view details)

Uploaded Python 3

File details

Details for the file prefab_classes-0.10.1.tar.gz.

File metadata

  • Download URL: prefab_classes-0.10.1.tar.gz
  • Upload date:
  • Size: 67.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for prefab_classes-0.10.1.tar.gz
Algorithm Hash digest
SHA256 4f287818f9fa809fe8ee4ffbfe848868860ff7b9b7662b81ceae3032f9b7c77e
MD5 16deb5b275629f2268b1e50ff56208cf
BLAKE2b-256 67b8a5865884ff03366a33014bd4e3d2bdc7428f9cc95aad701e7f0b80f73209

See more details on using hashes here.

File details

Details for the file prefab_classes-0.10.1-py3-none-any.whl.

File metadata

File hashes

Hashes for prefab_classes-0.10.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e09de17ec3054c5b6704dca699353623583bcb2b6532ffded62b87b7ca8fe109
MD5 4cb5bcb1eb7ef5be0acf7aff53b41ac6
BLAKE2b-256 915da853da8b2e721c6996920b067ebbd95767f9f155d80d70b8daccefe778df

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page