Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 3152 – Cofunctions

Author:
Gregory Ewing <greg.ewing at canterbury.ac.nz>
Status:
Rejected
Type:
Standards Track
Created:
13-Feb-2009
Python-Version:
3.3
Post-History:


Table of Contents

Abstract

A syntax is proposed for defining and calling a special type ofgenerator called a ‘cofunction’. It is designed to provide astreamlined way of writing generator-based coroutines, and allow theearly detection of certain kinds of error that are easily made whenwriting such code, which otherwise tend to cause hard-to-diagnosesymptoms.

This proposal builds on the ‘yield from’ mechanism described in PEP380, and describes some of the semantics of cofunctions in terms ofit. However, it would be possible to define and implement cofunctionsindependently ofPEP 380 if so desired.

Rejection

Seehttps://mail.python.org/pipermail/python-dev/2015-April/139503.html

Specification

Cofunction definitions

A new keywordcodef is introduced which is used in place ofdef to define a cofunction. A cofunction is a special kind ofgenerator having the following characteristics:

  1. A cofunction is always a generator, even if it does not contain anyyield oryieldfrom expressions.
  2. A cofunction cannot be called the same way as an ordinary function.An exception is raised if an ordinary call to a cofunction isattempted.

Cocalls

Calls from one cofunction to another are made by marking the call witha new keywordcocall. The expression

cocallf(*args,**kwds)

is semantically equivalent to

yield fromf.__cocall__(*args,**kwds)

except that the object returned by __cocall__ is expected to be aniterator, so the step of calling iter() on it is skipped.

The full syntax of a cocall expression is described by the followinggrammar lines:

atom:cocall|<existingalternativesforatom>cocall:'cocall'atomcotrailer*'('[arglist]')'cotrailer:'['subscriptlist']'|'.'NAME

Thecocall keyword is syntactically valid only inside acofunction. A SyntaxError will result if it is used in any othercontext.

Objects which implement __cocall__ are expected to return an objectobeying the iterator protocol. Cofunctions respond to __cocall__ thesame way as ordinary generator functions respond to __call__, i.e. byreturning a generator-iterator.

Certain objects that wrap other callable objects, notably boundmethods, will be given __cocall__ implementations that delegate to theunderlying object.

New builtins, attributes and C API functions

To facilitate interfacing cofunctions with non-coroutine code, there willbe a built-in functioncostart whose definition is equivalent to

defcostart(obj,*args,**kwds):returnobj.__cocall__(*args,**kwds)

There will also be a corresponding C API function

PyObject*PyObject_CoCall(PyObject*obj,PyObject*args,PyObject*kwds)

It is left unspecified for now whether a cofunction is a distinct typeof object or, like a generator function, is simply a specially-markedfunction instance. If the latter, a read-only boolean attribute__iscofunction__ should be provided to allow testing whether agiven function object is a cofunction.

Motivation and Rationale

Theyieldfrom syntax is reasonably self-explanatory when used forthe purpose of delegating part of the work of a generator to anotherfunction. It can also be used to good effect in the implementation ofgenerator-based coroutines, but it reads somewhat awkwardly when usedfor that purpose, and tends to obscure the true intent of the code.

Furthermore, using generators as coroutines is somewhat error-prone.If one forgets to useyieldfrom when it should have been used, oruses it when it shouldn’t have, the symptoms that result can beobscure and confusing.

Finally, sometimes there is a need for a function to be a coroutineeven though it does not yield anything, and in these cases it isnecessary to resort to kludges such asif0:yield to force it tobe a generator.

Thecodef andcocall constructs address the first issue bymaking the syntax directly reflect the intent, that is, that thefunction forms part of a coroutine.

The second issue is addressed by making it impossible to mix coroutineand non-coroutine code in ways that don’t make sense. If the rulesare violated, an exception is raised that points out exactly what andwhere the problem is.

Lastly, the need for dummy yields is eliminated by making the form ofdefinition determine whether the function is a coroutine, rather thanwhat it contains.

Prototype Implementation

An implementation in the form of patches to Python 3.1.2 can be foundhere:

http://www.cosc.canterbury.ac.nz/greg.ewing/python/generators/cofunctions.html

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-3152.rst

Last modified:2025-02-01 08:59:27 GMT


[8]ページ先頭

©2009-2025 Movatter.jp