exaloop / exaloop/codon

[Python-Semantic-gaps] Python compatibility gaps in Codon `with` semantics and syntax

Open
#787 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.8k
Forks
603
Avg merge
4d 23h
Merged PRs (30d)
6

Description

## Summary
Codon's current `with` implementation diverges from Python in several ways.

This issue tracks three compatibility gaps.

## 1. `as` binds the `class object`, not `__enter__()`'s return value

In Python:
```python
class Manager:
def __enter__(self):
return (1, 2)

def __exit__(self, exc_type, exc, tb):
return None

with Manager() as pair:
assert pair == (1, 2)
```
`pair` receives the `return value of __enter__() method`.

In current Codon, Identifier `pair` is not assigned tuple (1, 2). Instead, an instance of `class Manager` itself is assigned. So below code is more likely to work:
```python
class Manager:
def __enter__(self):
return None

def __exit__(self):
return None

def total(self):
return 3

with Manager() as pair:
assert pair.total() == 3

# pair must be “None” Object.
# But Actually, pair.total() works.

print("PASS classes_and_with")
```
This causes a clear Python compatibility gap.

## 2. `with ... as ...` only accepts a single identifier target
Python allows assignment targets such as tuple unpacking:

Current Codon grammar `only accepts an identifier` after as, so forms like these are rejected:
```peg
with Manager() as (x, y):
with Manager() as obj.attr:
with Manager() as arr[i]:
```
So the code below is not working.
```python
class Manager:
def __enter__(self):
return (1, 2)

def __exit__(self):
return None

with Manager() as (x, y):
assert x + y == 3

print("PASS with_tuple_unpack_target_python_compat")
```
The restriction appears in `codon/parser/peg/grammar.peg` , and the current `WithStmt AST` representation also only preserves a single identifier-like binding target.

This means the limitation is not only in parsing, but also in AST representation and lowering.

## 3. `__exit__` does not receive Python-style exception information
Python context managers receive:
```
__exit__(exc_type, exc, tb)
```
and may suppress exceptions by returning a truthy value.

Current Codon lowering calls `__exit__()` without exception arguments and does not model Python's suppression behavior. This means Python-style context manager cleanup/error handling semantics are not preserved.

But this likely requires more than a local with lowering change, as it touches the exception model, traceback representation, and with error-path lowering.

This item seems closely related to issue #758.

## Why these matter
As you can see in interop pattern of #758, These differences make Codon's with syntax look Python-compatible on the surface while behaving differently in meaningful cases. That can lead to subtle surprises when porting Python code or reasoning about context manager behavior.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.