Metadata-Version: 2.4
Name: ponn
Version: 0.1.0
Summary: Python object as namespace notation. A simple subset of python that represents objects as namespaces.
Author-email: Fábio Macêdo Mendes <fabiomacedomendes@gmail.com>
Requires-Python: >=3.13
Provides-Extra: cli
Requires-Dist: rich-click>=1.9.7; extra == 'cli'
Requires-Dist: rich>=14.3.3; extra == 'cli'
Description-Content-Type: text/markdown

What is Ponn?
=============

JSON, the ubiquitous JavaScript Object Notation is a nice format for data
exchange between machines, specially when humans may want to peek and quickly
understand the exchanged messages. JSON, however, is very limited in its data
types and it can be brittle to write by hand (no comments, no trailing commas,
no multi-line strings, etc).

Ponn is a simple subset of Python that represents objects as namespaces. It is
designed to be a more human-friendly alternative to JSON for configuration files
and sacrifices performance for ease of use (at least when used by Python
developers). It is very similar to PON, the Python Object Notation, but it
represents objects as Python modules instead of top-level dictionaries.

Ponn is also more flexible than PON (and JSON) in that it allows for more
complex data structures and some limited form of programming (e.g. you can use
variables, conditional statements, function execution, and imports).

Ponn files are thus valid Python files that can be executed and imported as
modules. This module simply provides a secure way to load Ponn files by checking
if they contain only valid Ponn constructs before executing them.

Usage
-----

To load a Ponn file, simply use the `load` function from the `ponn` module:

```python
from ponn import load

config = load("config.ponn")
print(config["database"]["host"])  # Accessing some inner structure 
```

The `load()` function returns a dictionary object mapping top-level variable
names to their values.


The Ponn subset
---------------

Ponn supports a subset of Python syntax that is safe to execute from untrusted
sources. Ponn can execute imports and call arbitrary functions from a whitelist,
so obviously the security depends on the security of the functions you allow to
be executed.


**What is allowed in Ponn files?**

- Comments
- Variable assignments (except __dunder__ variables)
- All python literals (strings, numbers, lists, tuples, dictionaries, sets, etc)
- Function calls to whitelisted functions
- Imports of whitelisted modules
- Conditional statements (if, elif, else) and ternary expressions
- Match statements
- Class definitions using dataclasses (and without methods)

**What is forbidden in Ponn files?**

- Any function calls not explicitly allowed in the whitelist
- Attribute access to __dunder__ methods or attributes (e.g. `__import__`, `__class__`, etc)
- Some built-in functions that are not in the whitelist (e.g. `open`, `eval`, `exec`, etc)
- Some functions are converted to no-op to prevent side effects (e.g. `print`).
- Loops and comprehensions (for, while) are not allowed to prevent unbounded execution.
- Function definitions (def, lambda) are not allowed to prevent infinite recursion.
- Class definitions of arbitrary classes.
- The with statement is not allowed to prevent resource leaks.
- The async and await keywords.

How does it work?
-----------------

Ponn uses the `ast` module to parse the Ponn file and check if it contains only
valid Ponn syntax. If the syntax is valid, it executes the file in a restricted
environment where only the whitelisted functions and modules are available. 
Some builtins are modified to prevent side effects or trigger errors when considered
unsafe (e.g. `print` is converted to a no-op, `open` raises an error, etc).

How safe is it?
---------------

Probably safe. Ponn is designed to be a safe subset of Python, but given the
extreme flexibility and reflective capabilities of Python, it is very difficult
to guarantee absolute safety. Many sandobox implementations have been broken in
the past, but they all aimed for a more generic sandboxed environment execution
(turing complete subsets of Python, not only flexible data representation).