clj-python / clj-python/libpython-clj

py/with macro doesn't bind the return value of __enter__ method

Aberta
#273 0 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Linguagem predominante
Clojure
Estrelas
1.2k
Forks
74
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

The py/with macro implementation doesn't correctly follow Python's with statement semantics. According to the Python documentation, the value bound in a with statement should be the return value of calling __enter__() on the context manager:

manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)  # This value should be bound to TARGET
hit_except = False

try:
    TARGET = value  # TARGET gets the return value of enter(manager)
    SUITE
...

Current Implementation

The current macro (with.clj#L45-L63) calls __enter__ but discards its return value:

(py-fn/call-attr ~varname "__enter__" nil)  ; Return value is ignored
(try
  (let [retval# (do ~@body)]
    ...

Expected Behavior

The bound variable should receive the return value of __enter__(), not the context manager itself:

(let [enter-result# (py-fn/call-attr ~varname "__enter__" nil)]
  (try
    (let [~varname enter-result#  ; Rebind to __enter__'s return value
          retval# (do ~@body)]
      ...

Why Current Tests Pass

The existing test in python_test.clj#L167 uses a WithObjClass where __enter__() returns None (implicitly), and the test methods are called on the original object. This masks the bug.

Real-World Example

A common Python pattern that fails with the current implementation:

with open('file.txt', 'r') as f:
    content = f.read()  # f should be the file object returned by __enter__

With the current macro, f would be bound to the unopened file path/manager rather than the file object returned by __enter__().

Next Steps

  1. Add test cases that verify this behavior (e.g., update WithObjClass.__enter__ to return a different object, or test with Python's built-in file context manager)
  2. Update the macro to correctly bind the return value of __enter__()

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece com src/libpython_clj2/python/with.clj#L45-L63 e o teste existente em test/libpython_clj2/python_test.clj#L167. Adicione cobertura usando um gerenciador de contexto cujo enter retorne um objeto diferente; em seguida, verifique se o valor vinculado é esse valor retornado e se o comportamento existente de with continua passando.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
clojure, python
Domínio
tooling
Tipo de issue
Bug
Dificuldade
2/5
Tempo estimado
1-3 horas
Status de atividade
Estagnada
Clareza
Claramente especificada
Facilidade para iniciantes
58/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.