diff --git a/Makefile b/Makefile index 50585463a..bd4291bbe 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ default: .state/docker-build-web: Dockerfile dev-requirements.txt base-requirements.txt # Build web container for this project - docker-compose build --force-rm web + docker compose build --force-rm web # Mark the state so we don't rebuild this needlessly. mkdir -p .state && touch .state/docker-build-web @@ -24,35 +24,35 @@ default: .state/db-initialized: .state/docker-build-web .state/db-migrated # Load all fixtures - docker-compose run --rm web ./manage.py loaddata fixtures/*.json + docker compose run --rm web ./manage.py loaddata fixtures/*.json # Mark the state so we don't rebuild this needlessly. mkdir -p .state && touch .state/db-initialized serve: .state/db-initialized - docker-compose up --remove-orphans + docker compose up --remove-orphans migrations: .state/db-initialized # Run Django makemigrations - docker-compose run --rm web ./manage.py makemigrations + docker compose run --rm web ./manage.py makemigrations migrate: .state/docker-build-web # Run Django migrate - docker-compose run --rm web ./manage.py migrate + docker compose run --rm web ./manage.py migrate manage: .state/db-initialized # Run Django manage to accept arbitrary arguments - docker-compose run --rm web ./manage.py $(filter-out $@,$(MAKECMDGOALS)) + docker compose run --rm web ./manage.py $(filter-out $@,$(MAKECMDGOALS)) shell: .state/db-initialized - docker-compose run --rm web ./manage.py shell + docker compose run --rm web ./manage.py shell clean: - docker-compose down -v + docker compose down -v rm -f .state/docker-build-web .state/db-initialized .state/db-migrated test: .state/db-initialized - docker-compose run --rm web ./manage.py test + docker compose run --rm web ./manage.py test docker_shell: .state/db-initialized - docker-compose run --rm web /bin/bash + docker compose run --rm web /bin/bash diff --git a/base-requirements.txt b/base-requirements.txt index 4f9c0aa39..680685cfc 100644 --- a/base-requirements.txt +++ b/base-requirements.txt @@ -52,5 +52,5 @@ django-extensions==3.1.4 django-import-export==2.7.1 pypandoc==1.12 -panflute==2.3.0 +panflute==2.3.1 Unidecode==1.3.8 diff --git a/infra/.terraform.lock.hcl b/infra/.terraform.lock.hcl index 165cd9357..5844f52bd 100644 --- a/infra/.terraform.lock.hcl +++ b/infra/.terraform.lock.hcl @@ -22,3 +22,25 @@ provider "registry.terraform.io/fastly/fastly" { "zh:ec8d899cafd925d3492f00c6523c90599aebc43c1373ad4bd6c55f12d2376230", ] } + +provider "registry.terraform.io/signalsciences/sigsci" { + version = "3.3.0" + constraints = "3.3.0" + hashes = [ + "h1:DIoFVzfofY8lQSxFTw9wmQQC28PPMq+5l3xbPNw9gLc=", + "zh:07c25e1cca9c13314429a8430c2e999ad94c7d5e2f2a11501ee2608182387e61", + "zh:07daf79b672f3e0bec7b48e3ac8dcdeec02af06b10d653bd8158a74236b0746b", + "zh:1e24a050c3d3571ec3224c4bb5c82635caf636e707b5993a1cc97c9a1f19fa8f", + "zh:24293ae24b3de13bda8512c47967f01814724805396a1bfbfbfc56f5627615cc", + "zh:2cc6ba7a38d9854146d1d05f4b7a2f8e18a33c1267b768506cbe37168dad01dc", + "zh:42065bfee0cfde04096d6140c65379253359bed49b481a97aff70aa65bf568b3", + "zh:6f7f4d96967dfd92f098b57647d396679b70d92548db6d100c4dc8723569d175", + "zh:a2e4431f045cef16ed152c0d1f8a377b6468351b775ad1ca7ce3fe74fb874be2", + "zh:b0ed1cb03d6f191fe211f10bb59ef8daed6f89e3d99136e7bb5d38f2ac72fa45", + "zh:b61ea18442a65d27b97dd1cd43bdd8d0a56c2b4b8db6355480e89f8507c6782a", + "zh:c31bb2f50ac2a636758f93afec0b9d173be6d7d7476f9e250b4554e70c6d8d82", + "zh:cb7337f7b4678ad7ece28741069c07ce5601d2a103a9667db568cf10ed0ee5a2", + "zh:d521a7dac51733aebb0905e25b8f7c1279d83c06136e87826e010c667528fd3e", + "zh:ef791688acee3b8b1191b3c6dc54dabf69612dbfb666720280b492ce348a3a06", + ] +} diff --git a/infra/cdn/README.md b/infra/cdn/README.md index 6ebe5a637..a667f63db 100644 --- a/infra/cdn/README.md +++ b/infra/cdn/README.md @@ -29,5 +29,29 @@ N/A ## Requirements Tested on -- Tested on Terraform 1.8.5 -- Fastly provider 5.13.0 \ No newline at end of file +- Tested on Terraform 1.9.5 +- Fastly provider 5.13.0 + +# Fastly's NGWAF + +This module also conditionally can set up the Fastly Next-Gen Web Application Firewall (NGWAF) +for our Fastly services related to python.org / test.python.org. + +## Usage + +```hcl +module "fastly_production" { + source = "./cdn" + + ... + activate_ngwaf_service = true + ... +} +``` + +## Requirements + +Tested on +- Terraform 1.9.5 +- Fastly provider 5.13.0 +- SigSci provider 3.3.0 \ No newline at end of file diff --git a/infra/cdn/main.tf b/infra/cdn/main.tf index 12d1fbba4..eb6c6858c 100644 --- a/infra/cdn/main.tf +++ b/infra/cdn/main.tf @@ -342,4 +342,73 @@ resource "fastly_service_vcl" "python_org" { response = "Forbidden" status = 403 } + + dynamic "dictionary" { + for_each = var.activate_ngwaf_service ? [1] : [] + content { + name = var.edge_security_dictionary + } + } + + dynamic "dynamicsnippet" { + for_each = var.activate_ngwaf_service ? [1] : [] + content { + name = "ngwaf_config_init" + type = "init" + priority = 0 + } + } + + dynamic "dynamicsnippet" { + for_each = var.activate_ngwaf_service ? [1] : [] + content { + name = "ngwaf_config_miss" + type = "miss" + priority = 9000 + } + } + + dynamic "dynamicsnippet" { + for_each = var.activate_ngwaf_service ? [1] : [] + content { + name = "ngwaf_config_pass" + type = "pass" + priority = 9000 + } + } + + dynamic "dynamicsnippet" { + for_each = var.activate_ngwaf_service ? [1] : [] + content { + name = "ngwaf_config_deliver" + type = "deliver" + priority = 9000 + } + } + + lifecycle { + ignore_changes = [ + product_enablement, + ] + } +} + +output "service_id" { + value = fastly_service_vcl.python_org.id + description = "The ID of the Fastly service" +} + +output "backend_address" { + value = var.backend_address + description = "The backend address for the service." +} + +output "service_name" { + value = var.name + description = "The name of the Fastly service" +} + +output "domain" { + value = var.domain + description = "The domain of the Fastly service" } diff --git a/infra/cdn/ngwaf.tf b/infra/cdn/ngwaf.tf new file mode 100644 index 000000000..8ca3a61f6 --- /dev/null +++ b/infra/cdn/ngwaf.tf @@ -0,0 +1,49 @@ +resource "fastly_service_dictionary_items" "edge_security_dictionary_items" { + count = var.activate_ngwaf_service ? 1 : 0 + service_id = fastly_service_vcl.python_org.id + dictionary_id = one([for d in fastly_service_vcl.python_org.dictionary : d.dictionary_id if d.name == var.edge_security_dictionary]) + items = { + Enabled : "100" + } +} + +resource "fastly_service_dynamic_snippet_content" "ngwaf_config_snippets" { + for_each = var.activate_ngwaf_service ? toset(["init", "miss", "pass", "deliver"]) : [] + service_id = fastly_service_vcl.python_org.id + snippet_id = one([for d in fastly_service_vcl.python_org.dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_${each.key}"]) + content = "### Terraform managed ngwaf_config_${each.key}" + manage_snippets = false +} + +# NGWAF Edge Deployment on SignalSciences.net +resource "sigsci_edge_deployment" "ngwaf_edge_site_service" { + count = var.activate_ngwaf_service ? 1 : 0 + provider = sigsci.firewall + site_short_name = var.ngwaf_site_name +} + +resource "sigsci_edge_deployment_service" "ngwaf_edge_service_link" { + count = var.activate_ngwaf_service ? 1 : 0 + provider = sigsci.firewall + site_short_name = var.ngwaf_site_name + fastly_sid = fastly_service_vcl.python_org.id + activate_version = var.activate_ngwaf_service + percent_enabled = 100 + depends_on = [ + sigsci_edge_deployment.ngwaf_edge_site_service, + fastly_service_vcl.python_org, + fastly_service_dictionary_items.edge_security_dictionary_items, + fastly_service_dynamic_snippet_content.ngwaf_config_snippets, + ] +} + +resource "sigsci_edge_deployment_service_backend" "ngwaf_edge_service_backend_sync" { + count = var.activate_ngwaf_service ? 1 : 0 + provider = sigsci.firewall + site_short_name = var.ngwaf_site_name + fastly_sid = fastly_service_vcl.python_org.id + fastly_service_vcl_active_version = fastly_service_vcl.python_org.active_version + depends_on = [ + sigsci_edge_deployment_service.ngwaf_edge_service_link, + ] +} diff --git a/infra/cdn/providers.tf b/infra/cdn/providers.tf index 201f5de4a..bdee7a807 100644 --- a/infra/cdn/providers.tf +++ b/infra/cdn/providers.tf @@ -2,3 +2,11 @@ provider "fastly" { alias = "cdn" api_key = var.fastly_key } + +provider "sigsci" { + alias = "firewall" + corp = var.ngwaf_corp_name + email = var.ngwaf_email + auth_token = var.ngwaf_token + fastly_api_key = var.fastly_key +} diff --git a/infra/cdn/variables.tf b/infra/cdn/variables.tf index 4cbf6db6e..5c1be4562 100644 --- a/infra/cdn/variables.tf +++ b/infra/cdn/variables.tf @@ -40,4 +40,38 @@ variable "backend_address" { variable "default_ttl" { type = number description = "The default TTL for the service." -} \ No newline at end of file +} + +## NGWAF +variable "activate_ngwaf_service" { + type = bool + description = "Whether to activate the NGWAF service." +} +variable "edge_security_dictionary" { + type = string + description = "The dictionary name for the Edge Security product." + default = "" +} +variable "ngwaf_corp_name" { + type = string + description = "Corp name for NGWAF" + default = "python" +} +variable "ngwaf_site_name" { + type = string + description = "Site SHORT name for NGWAF" + + validation { + condition = can(regex("^(test|stage|prod)$", var.ngwaf_site_name)) + error_message = "'ngwaf_site_name' must be one of the following: test, stage, or prod" + } +} +variable "ngwaf_email" { + type = string + description = "Email address associated with the token for the NGWAF API." +} +variable "ngwaf_token" { + type = string + description = "Secret token for the NGWAF API." + sensitive = true +} diff --git a/infra/cdn/versions.tf b/infra/cdn/versions.tf index da9c01f79..f8c137ba6 100644 --- a/infra/cdn/versions.tf +++ b/infra/cdn/versions.tf @@ -4,5 +4,9 @@ terraform { source = "fastly/fastly" version = "5.13.0" } + sigsci = { + source = "signalsciences/sigsci" + version = "3.3.0" + } } } diff --git a/infra/main.tf b/infra/main.tf index b3ec26a77..90c2ba9c5 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -12,15 +12,20 @@ module "fastly_production" { fastly_key = var.FASTLY_API_KEY fastly_header_token = var.FASTLY_HEADER_TOKEN s3_logging_keys = var.fastly_s3_logging + + ngwaf_site_name = "prod" + ngwaf_email = "infrastructure-staff@python.org" + ngwaf_token = var.ngwaf_token + activate_ngwaf_service = false } module "fastly_staging" { source = "./cdn" - name = "test.python.org" - domain = "test.python.org" - subdomain = "www.test.python.org" - extra_domains = ["www.test.python.org"] + name = "test.python.org" + domain = "test.python.org" + subdomain = "www.test.python.org" + extra_domains = ["www.test.python.org"] # TODO: adjust to test-pythondotorg when done testing NGWAF backend_address = "pythondotorg.ingress.us-east-2.psfhosted.computer" default_ttl = 3600 @@ -29,4 +34,9 @@ module "fastly_staging" { fastly_key = var.FASTLY_API_KEY fastly_header_token = var.FASTLY_HEADER_TOKEN s3_logging_keys = var.fastly_s3_logging + + ngwaf_site_name = "test" + ngwaf_email = "infrastructure-staff@python.org" + ngwaf_token = var.ngwaf_token + activate_ngwaf_service = true } diff --git a/infra/variables.tf b/infra/variables.tf index ec23b23ec..33fc1dda5 100644 --- a/infra/variables.tf +++ b/infra/variables.tf @@ -17,4 +17,9 @@ variable "fastly_s3_logging" { type = map(string) description = "S3 bucket keys for Fastly logging" sensitive = true -} \ No newline at end of file +} +variable "ngwaf_token" { + type = string + description = "Secret token for the NGWAF API." + sensitive = true +} diff --git a/jobs/migrations/0022_alter_jobtype_options_alter_job_job_types_and_more.py b/jobs/migrations/0022_alter_jobtype_options_alter_job_job_types_and_more.py new file mode 100644 index 000000000..4013f2376 --- /dev/null +++ b/jobs/migrations/0022_alter_jobtype_options_alter_job_job_types_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.16 on 2024-09-13 17:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('jobs', '0021_alter_job_creator_alter_job_last_modified_by_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='jobtype', + options={'ordering': ('name',), 'verbose_name': 'job types', 'verbose_name_plural': 'job types'}, + ), + migrations.AlterField( + model_name='job', + name='job_types', + field=models.ManyToManyField(blank=True, limit_choices_to={'active': True}, related_name='jobs', to='jobs.jobtype', verbose_name='Job types'), + ), + migrations.AlterField( + model_name='job', + name='other_job_type', + field=models.CharField(blank=True, max_length=100, verbose_name='Other job types'), + ), + ] diff --git a/jobs/models.py b/jobs/models.py index 54722873d..8b232fb93 100644 --- a/jobs/models.py +++ b/jobs/models.py @@ -30,8 +30,8 @@ class JobType(NameSlugModel): objects = JobTypeQuerySet.as_manager() class Meta: - verbose_name = 'job technologies' - verbose_name_plural = 'job technologies' + verbose_name = 'job types' + verbose_name_plural = 'job types' ordering = ('name', ) @@ -59,11 +59,11 @@ class Job(ContentManageable): JobType, related_name='jobs', blank=True, - verbose_name='Job technologies', + verbose_name='Job types', limit_choices_to={'active': True}, ) other_job_type = models.CharField( - verbose_name='Other job technologies', + verbose_name='Other job types', max_length=100, blank=True, ) diff --git a/pages/models.py b/pages/models.py index 9b67997e1..c3973ce68 100644 --- a/pages/models.py +++ b/pages/models.py @@ -137,6 +137,8 @@ def purge_fastly_cache(sender, instance, **kwargs): Requires settings.FASTLY_API_KEY being set """ purge_url(f'/{instance.path}') + if not instance.path.endswith('/'): + purge_url(f'/{instance.path}/') def page_image_path(instance, filename): diff --git a/peps/__init__.py b/peps/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/peps/apps.py b/peps/apps.py deleted file mode 100644 index a59996f2a..000000000 --- a/peps/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class PepsAppConfig(AppConfig): - - name = 'peps' diff --git a/peps/converters.py b/peps/converters.py deleted file mode 100644 index 1d63d7438..000000000 --- a/peps/converters.py +++ /dev/null @@ -1,262 +0,0 @@ -import functools -import datetime -import re -import os - -from bs4 import BeautifulSoup - -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.core.files import File -from django.db.models import Max - -from pages.models import Page, Image - -PEP_TEMPLATE = 'pages/pep-page.html' -pep_url = lambda num: f'dev/peps/pep-{num}/' - - -def get_peps_last_updated(): - last_update = Page.objects.filter( - path__startswith='dev/peps', - ).aggregate(Max('updated')).get('updated__max') - if last_update is None: - return datetime.datetime( - 1970, 1, 1, tzinfo=datetime.timezone( - datetime.timedelta(0) - ) - ) - return last_update - - -def convert_pep0(artifact_path): - """ - Take existing generated pep-0000.html and convert to something suitable - for a Python.org Page returns the core body HTML necessary only - """ - pep0_path = os.path.join(artifact_path, 'pep-0000.html') - pep0_content = open(pep0_path).read() - data = convert_pep_page(0, pep0_content) - if data is None: - return - return data['content'] - - -def get_pep0_page(artifact_path, commit=True): - """ - Using convert_pep0 above, create a CMS ready pep0 page and return it - - pep0 is used as the directory index, but it's also an actual pep, so we - return both Page objects. - """ - pep0_content = convert_pep0(artifact_path) - if pep0_content is None: - return None, None - pep0_page, _ = Page.objects.get_or_create(path='dev/peps/') - pep0000_page, _ = Page.objects.get_or_create(path='dev/peps/pep-0000/') - for page in [pep0_page, pep0000_page]: - page.content = pep0_content - page.content_markup_type = 'html' - page.title = "PEP 0 -- Index of Python Enhancement Proposals (PEPs)" - page.template_name = PEP_TEMPLATE - - if commit: - page.save() - - return pep0_page, pep0000_page - - -def fix_headers(soup, data): - """ Remove empty or unwanted headers and find our title """ - header_rows = soup.find_all('th') - for t in header_rows: - if 'Version:' in t.text: - if t.next_sibling.text == '$Revision$': - t.parent.extract() - if t.next_sibling.text == '': - t.parent.extract() - if 'Last-Modified:' in t.text: - if '$Date$'in t.next_sibling.text: - t.parent.extract() - if t.next_sibling.text == '': - t.parent.extract() - if t.text == 'Title:': - data['title'] = t.next_sibling.text - if t.text == 'Content-Type:': - t.parent.extract() - if 'Version:' in t.text and 'N/A' in t.next_sibling.text: - t.parent.extract() - - return soup, data - - -def convert_pep_page(pep_number, content): - """ - Handle different formats that pep2html.py outputs - """ - data = { - 'title': None, - } - # Remove leading zeros from PEP number for display purposes - pep_number_humanize = re.sub(r'^0+', '', str(pep_number)) - - if '' in content: - soup = BeautifulSoup(content, 'lxml') - data['title'] = soup.title.text - - if not re.search(r'PEP \d+', data['title']): - data['title'] = 'PEP {} -- {}'.format( - pep_number_humanize, - soup.title.text, - ) - - header = soup.body.find('div', class_="header") - header, data = fix_headers(header, data) - data['header'] = str(header) - - main_content = soup.body.find('div', class_="content") - - data['main_content'] = str(main_content) - data['content'] = ''.join([ - data['header'], - data['main_content'] - ]) - - else: - soup = BeautifulSoup(content, 'lxml') - - soup, data = fix_headers(soup, data) - if not data['title']: - data['title'] = f"PEP {pep_number_humanize} -- " - else: - if not re.search(r'PEP \d+', data['title']): - data['title'] = "PEP {} -- {}".format( - pep_number_humanize, - data['title'], - ) - - data['content'] = str(soup) - - # Fix PEP links - pep_content = BeautifulSoup(data['content'], 'lxml') - body_links = pep_content.find_all("a") - - pep_href_re = re.compile(r'pep-(\d+)\.html') - - for b in body_links: - m = pep_href_re.search(b.attrs['href']) - - # Skip anything not matching 'pep-XXXX.html' - if not m: - continue - - b.attrs['href'] = f'/dev/peps/pep-{m.group(1)}/' - - # Return early if 'html' or 'body' return None. - if pep_content.html is None or pep_content.body is None: - return - - # Strip and tags. - pep_content.html.unwrap() - pep_content.body.unwrap() - - data['content'] = str(pep_content) - return data - - -def get_pep_page(artifact_path, pep_number, commit=True): - """ - Given a pep_number retrieve original PEP source text, rst, or html. - Get or create the associated Page and return it - """ - pep_path = os.path.join(artifact_path, f'pep-{pep_number}.html') - if not os.path.exists(pep_path): - print(f"PEP Path '{pep_path}' does not exist, skipping") - return - - pep_content = convert_pep_page(pep_number, open(pep_path).read()) - if pep_content is None: - return None - pep_rst_source = os.path.join( - artifact_path, f'pep-{pep_number}.rst', - ) - pep_ext = '.rst' if os.path.exists(pep_rst_source) else '.txt' - source_link = 'https://github.com/python/peps/blob/master/pep-{}{}'.format( - pep_number, pep_ext) - pep_content['content'] += """Source: {0}""".format(source_link) - - pep_page, _ = Page.objects.get_or_create(path=pep_url(pep_number)) - - pep_page.title = pep_content['title'] - - pep_page.content = pep_content['content'] - pep_page.content_markup_type = 'html' - pep_page.template_name = PEP_TEMPLATE - - if commit: - pep_page.save() - - return pep_page - - -def add_pep_image(artifact_path, pep_number, path): - image_path = os.path.join(artifact_path, path) - if not os.path.exists(image_path): - print(f"Image Path '{image_path}' does not exist, skipping") - return - - try: - page = Page.objects.get(path=pep_url(pep_number)) - except Page.DoesNotExist: - print(f"Could not find backing PEP {pep_number}") - return - - # Find existing images, we have to loop here as we can't use the ORM - # to query against image__path - existing_images = Image.objects.filter(page=page) - - FOUND = False - for image in existing_images: - if image.image.name.endswith(path): - FOUND = True - break - - if not FOUND: - image = Image(page=page) - - with open(image_path, 'rb') as image_obj: - image.image.save(path, File(image_obj)) - image.save() - - # Old images used to live alongside html, but now they're in different - # places, so update the page accordingly. - soup = BeautifulSoup(page.content.raw, 'lxml') - for img_tag in soup.findAll('img'): - if img_tag['src'] == path: - img_tag['src'] = image.image.url - - page.content.raw = str(soup) - page.save() - - return image - - -def get_peps_rss(artifact_path): - rss_feed = os.path.join(artifact_path, 'peps.rss') - if not os.path.exists(rss_feed): - return - - page, _ = Page.objects.get_or_create( - path="dev/peps/peps.rss", - template_name="pages/raw.html", - ) - - with open(rss_feed) as rss_content: - content = rss_content.read() - - page.content = content - page.is_published = True - page.content_type = "application/rss+xml" - page.save() - - return page diff --git a/peps/management/__init__.py b/peps/management/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/peps/management/commands/__init__.py b/peps/management/commands/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/peps/management/commands/dump_pep_pages.py b/peps/management/commands/dump_pep_pages.py deleted file mode 100644 index 549b8faa4..000000000 --- a/peps/management/commands/dump_pep_pages.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.core import serializers -from django.core.management import BaseCommand - -from pages.models import Page - - -class Command(BaseCommand): - """ - Dump PEP related Pages as indented JSON - """ - help = "Dump PEP related Pages as indented JSON" - - def handle(self, **options): - qs = Page.objects.filter(path__startswith='dev/peps/') - - serializers.serialize( - format='json', - queryset=qs, - indent=4, - stream=self.stdout, - ) diff --git a/peps/management/commands/generate_pep_pages.py b/peps/management/commands/generate_pep_pages.py deleted file mode 100644 index 9f9010584..000000000 --- a/peps/management/commands/generate_pep_pages.py +++ /dev/null @@ -1,143 +0,0 @@ -import re -import os - -from contextlib import ExitStack -from tarfile import TarFile -from tempfile import TemporaryDirectory, TemporaryFile - -import requests - -from django.core.management import BaseCommand -from django.conf import settings - -from dateutil.parser import parse as parsedate - -from peps.converters import ( - get_pep0_page, get_pep_page, add_pep_image, get_peps_rss, get_peps_last_updated -) - -pep_number_re = re.compile(r'pep-(\d+)') - - -class Command(BaseCommand): - """ - Generate CMS Pages from flat file PEP data. - - Run this command AFTER normal RST -> HTML PEP transformation from the PEP - repository has happened. This works on the HTML files created during that - process. - - For verbose output run this with: - - ./manage.py generate_pep_pages --verbosity=2 - """ - help = "Generate PEP Page objects from rendered HTML" - - def is_pep_page(self, path): - return path.startswith('pep-') and path.endswith('.html') - - def is_image(self, path): - # All images are pngs - return path.endswith('.png') - - def handle(self, **options): - verbosity = int(options['verbosity']) - - def verbose(msg): - """ Output wrapper """ - if verbosity > 1: - print(msg) - - verbose("== Starting PEP page generation") - - with ExitStack() as stack: - if settings.PEP_REPO_PATH is not None: - artifacts_path = settings.PEP_REPO_PATH - else: - verbose(f"== Fetching PEP artifact from {settings.PEP_ARTIFACT_URL}") - temp_file = self.get_artifact_tarball(stack) - if not temp_file: - verbose("== No update to artifacts, we're done here!") - return - temp_dir = stack.enter_context(TemporaryDirectory()) - tar_ball = stack.enter_context(TarFile.open(fileobj=temp_file, mode='r:gz')) - tar_ball.extractall(path=temp_dir, numeric_owner=False) - - artifacts_path = os.path.join(temp_dir, 'peps') - - verbose("Generating RSS Feed") - peps_rss = get_peps_rss(artifacts_path) - if not peps_rss: - verbose("Could not find generated RSS feed. Skipping.") - - verbose("Generating PEP0 index page") - pep0_page, _ = get_pep0_page(artifacts_path) - if pep0_page is None: - verbose("HTML version of PEP 0 cannot be generated.") - return - - image_paths = set() - - # Find pep pages - for f in os.listdir(artifacts_path): - - if self.is_image(f): - verbose(f"- Deferring import of image '{f}'") - image_paths.add(f) - continue - - # Skip files we aren't looking for - if not self.is_pep_page(f): - verbose(f"- Skipping non-PEP file '{f}'") - continue - - if 'pep-0000.html' in f: - verbose("- Skipping duplicate PEP0 index") - continue - - verbose(f"Generating PEP Page from '{f}'") - pep_match = pep_number_re.match(f) - if pep_match: - pep_number = pep_match.groups(1)[0] - p = get_pep_page(artifacts_path, pep_number) - if p is None: - verbose( - "- HTML version PEP {!r} cannot be generated.".format( - pep_number - ) - ) - verbose(f"====== Title: '{p.title}'") - else: - verbose(f"- Skipping invalid '{f}'") - - # Find pep images. This needs to happen afterwards, because we need - for img in image_paths: - pep_match = pep_number_re.match(img) - if pep_match: - pep_number = pep_match.groups(1)[0] - verbose("Generating image for PEP {} at '{}'".format( - pep_number, img)) - add_pep_image(artifacts_path, pep_number, img) - else: - verbose(f"- Skipping non-PEP related image '{img}'") - - verbose("== Finished") - - def get_artifact_tarball(self, stack): - artifact_url = settings.PEP_ARTIFACT_URL - if not artifact_url.startswith(('http://', 'https://')): - return stack.enter_context(open(artifact_url, 'rb')) - - peps_last_updated = get_peps_last_updated() - with requests.get(artifact_url, stream=True) as r: - artifact_last_modified = parsedate(r.headers['last-modified']) - if peps_last_updated > artifact_last_modified: - return - - temp_file = stack.enter_context(TemporaryFile()) - for chunk in r.iter_content(chunk_size=8192): - if chunk: - temp_file.write(chunk) - - temp_file.seek(0) - return temp_file diff --git a/peps/models.py b/peps/models.py deleted file mode 100644 index e45cd9cd1..000000000 --- a/peps/models.py +++ /dev/null @@ -1 +0,0 @@ -# Intentially left blank diff --git a/peps/templatetags/__init__.py b/peps/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/peps/templatetags/peps.py b/peps/templatetags/peps.py deleted file mode 100644 index 9d90afe24..000000000 --- a/peps/templatetags/peps.py +++ /dev/null @@ -1,16 +0,0 @@ -from django import template - -from pages.models import Page - -register = template.Library() - - -@register.simple_tag -def get_newest_pep_pages(limit=5): - """ Retrieve the most recently added PEPs """ - latest_peps = Page.objects.filter( - path__startswith='dev/peps/', - is_published=True, - ).order_by('-created')[:limit] - - return latest_peps diff --git a/peps/tests/__init__.py b/peps/tests/__init__.py deleted file mode 100644 index 944cc90aa..000000000 --- a/peps/tests/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -import os - -from django.conf import settings - -FAKE_PEP_REPO = os.path.join(settings.BASE, 'peps/tests/peps/') -FAKE_PEP_ARTIFACT = os.path.join(settings.BASE, 'peps/tests/peps.tar.gz') diff --git a/peps/tests/peps.tar.gz b/peps/tests/peps.tar.gz deleted file mode 100644 index edaa86b79..000000000 Binary files a/peps/tests/peps.tar.gz and /dev/null differ diff --git a/peps/tests/peps/pep-0000.html b/peps/tests/peps/pep-0000.html deleted file mode 100644 index c11c027c9..000000000 --- a/peps/tests/peps/pep-0000.html +++ /dev/null @@ -1,1030 +0,0 @@ - - - - - PEP 0 -- Index of Python Enhancement Proposals (PEPs) - - - - - - -
- - - - - - - - - -
PEP: 0
Title: Index of Python Enhancement Proposals (PEPs)
Version: N/A
Last-Modified: 2014-09-26
Author: David Goodger <goodger at python.org>, Barry Warsaw <barry at python.org>
Status: Active
Type: Informational
Created: 13-Jul-2000
-
-
-
-

Introduction

-
-    This PEP contains the index of all Python Enhancement Proposals,
-    known as PEPs.  PEP numbers are assigned by the PEP editors, and
-    once assigned are never changed[1].  The Mercurial history[2] of
-    the PEP texts represent their historical record.
-
-
-
-

Index by Category

-
-     num  title                                                   owner
-     ---  -----                                                   -----
-
- Meta-PEPs (PEPs about PEPs or Processes)
-
- P     1  PEP Purpose and Guidelines                              Warsaw, Hylton, Goodger, Coghlan
- P     4  Deprecation of Standard Modules                         von Löwis
- P     5  Guidelines for Language Evolution                       Prescod
- P     6  Bug Fix Releases                                        Aahz, Baxter
- P     7  Style Guide for C Code                                  GvR
- P     8  Style Guide for Python Code                             GvR, Warsaw, Coghlan
- P     9  Sample Plaintext PEP Template                           Warsaw
- P    10  Voting Guidelines                                       Warsaw
- P    11  Removing support for little used platforms              von Löwis
- P    12  Sample reStructuredText PEP Template                    Goodger, Warsaw
-
- Other Informational PEPs
-
- I    20  The Zen of Python                                       Peters
- I   101  Doing Python Releases 101                               Warsaw, GvR
- IF  247  API for Cryptographic Hash Functions                    Kuchling
- IF  248  Python Database API Specification v1.0                  Lemburg
- IF  249  Python Database API Specification v2.0                  Lemburg
- I   257  Docstring Conventions                                   Goodger, GvR
- IF  272  API for Block Encryption Algorithms v1.0                Kuchling
- I   287  reStructuredText Docstring Format                       Goodger
- I   290  Code Migration and Modernization                        Hettinger
- IF  291  Backward Compatibility for the Python 2 Standard ...    Norwitz
- IF  333  Python Web Server Gateway Interface v1.0                Eby
- I   373  Python 2.7 Release Schedule                             Peterson
- I   392  Python 3.2 Release Schedule                             Brandl
- I   394  The "python" Command on Unix-Like Systems               Staley, Coghlan
- I   398  Python 3.3 Release Schedule                             Brandl
- IF  399  Pure Python/C Accelerator Module Compatibility ...      Cannon
- IF  404  Python 2.8 Un-release Schedule                          Warsaw
- IA  411  Provisional packages in the Python standard library     Coghlan, Bendersky
- I   429  Python 3.4 Release Schedule                             Hastings
- IF  430  Migrating to Python 3 as the default online ...         Coghlan
- I   434  IDLE Enhancement Exception for All Branches             Rovito, Reedy
- IA  440  Version Identification and Dependency Specification     Coghlan, Stufft
- I   478  Python 3.5 Release Schedule                             Hastings
- IF 3333  Python Web Server Gateway Interface v1.0.1              Eby
-
- Accepted PEPs (accepted; may not be implemented yet)
-
- SA  345  Metadata for Python Software Packages 1.2               Jones
- SA  376  Database of Installed Python Distributions              Ziadé
- SA  425  Compatibility Tags for Built Distributions              Holth
- SA  427  The Wheel Binary Package Format 1.0                     Holth
- SA  461  Adding % formatting to bytes and bytearray              Furman
- SA  471  os.scandir() function -- a better and faster ...        Hoyt
- SA  477  Backport ensurepip (PEP 453) to Python 2.7              Stufft, Coghlan
- SA 3121  Extension Module Initialization and Finalization        von Löwis
-
- Open PEPs (under consideration)
-
- S   381  Mirroring infrastructure for PyPI                       Ziadé, v. Löwis
- P   387  Backwards Compatibility Policy                          Peterson
- S   426  Metadata for Python Software Packages 2.0               Coghlan, Holth, Stufft
- S   431  Time zone support improvements                          Regebro
- S   432  Simplifying the CPython startup sequence                Coghlan
- S   436  The Argument Clinic DSL                                 Hastings
- S   441  Improving Python ZIP Application Support                Holth
- S   447  Add __getdescriptor__ method to metaclass               Oussoren
- S   448  Additional Unpacking Generalizations                    Landau
- I   452  API for Cryptographic Hash Functions v2.0               Kuchling, Heimes
- S   455  Adding a key-transforming dictionary to collections     Pitrou
- I   457  Syntax For Positional-Only Parameters                   Hastings
- S   458  Surviving a Compromise of PyPI                          Kuppusamy, Stufft, Cappos
- S   459  Standard Metadata Extensions for Python Software ...    Coghlan
- S   463  Exception-catching expressions                          Angelico
- S   467  Minor API improvements for binary sequences             Coghlan
- S   468  Preserving the order of \*\*kwargs in a function.       Snow
- P   470  Using Multi Index Support for External to PyPI ...      Stufft
- S   472  Support for indexing with keyword arguments             Borini, Martinot-Lagarde
- S   473  Adding structured data to built-in exceptions           Kreft
- S   475  Retry system calls failing with EINTR                   Natali, Stinner
- S   476  Enabling certificate verification by default for ...    Gaynor
-
- Finished PEPs (done, implemented in code repository)
-
- SF  100  Python Unicode Integration                              Lemburg
- SF  201  Lockstep Iteration                                      Warsaw
- SF  202  List Comprehensions                                     Warsaw
- SF  203  Augmented Assignments                                   Wouters
- SF  205  Weak References                                         Drake
- SF  207  Rich Comparisons                                        GvR, Ascher
- SF  208  Reworking the Coercion Model                            Schemenauer, Lemburg
- SF  214  Extended Print Statement                                Warsaw
- SF  217  Display Hook for Interactive Use                        Zadka
- SF  218  Adding a Built-In Set Object Type                       Wilson, Hettinger
- SF  221  Import As                                               Wouters
- SF  223  Change the Meaning of \x Escapes                        Peters
- SF  227  Statically Nested Scopes                                Hylton
- SF  229  Using Distutils to Build Python                         Kuchling
- SF  230  Warning Framework                                       GvR
- SF  232  Function Attributes                                     Warsaw
- SF  234  Iterators                                               Yee, GvR
- SF  235  Import on Case-Insensitive Platforms                    Peters
- SF  236  Back to the __future__                                  Peters
- SF  237  Unifying Long Integers and Integers                     Zadka, GvR
- SF  238  Changing the Division Operator                          Zadka, GvR
- SF  241  Metadata for Python Software Packages                   Kuchling
- SF  250  Using site-packages on Windows                          Moore
- SF  252  Making Types Look More Like Classes                     GvR
- SF  253  Subtyping Built-in Types                                GvR
- SF  255  Simple Generators                                       Schemenauer, Peters, Hetland
- SF  260  Simplify xrange()                                       GvR
- SF  261  Support for "wide" Unicode characters                   Prescod
- SF  263  Defining Python Source Code Encodings                   Lemburg, von Löwis
- SF  264  Future statements in simulated shells                   Hudson
- SF  273  Import Modules from Zip Archives                        Ahlstrom
- SF  274  Dict Comprehensions                                     Warsaw
- SF  277  Unicode file name support for Windows NT                Hodgson
- SF  278  Universal Newline Support                               Jansen
- SF  279  The enumerate() built-in function                       Hettinger
- SF  282  A Logging System                                        Sajip, Mick
- SF  285  Adding a bool type                                      GvR
- SF  289  Generator Expressions                                   Hettinger
- SF  292  Simpler String Substitutions                            Warsaw
- SF  293  Codec Error Handling Callbacks                          Dörwald
- SF  301  Package Index and Metadata for Distutils                Jones
- SF  302  New Import Hooks                                        JvR, Moore
- SF  305  CSV File API                                            Altis, Cole, McNamara, Montanaro, Wells
- SF  307  Extensions to the pickle protocol                       GvR, Peters
- SF  308  Conditional Expressions                                 GvR, Hettinger
- SF  309  Partial Function Application                            Harris
- SF  311  Simplified Global Interpreter Lock Acquisition for ...  Hammond
- SF  314  Metadata for Python Software Packages v1.1              Kuchling, Jones
- SF  318  Decorators for Functions and Methods                    Smith
- SF  322  Reverse Iteration                                       Hettinger
- SF  324  subprocess - New process module                         Astrand
- SF  327  Decimal Data Type                                       Batista
- SF  328  Imports: Multi-Line and Absolute/Relative               Aahz
- SF  331  Locale-Independent Float/String Conversions             Reis
- SF  338  Executing modules as scripts                            Coghlan
- SF  341  Unifying try-except and try-finally                     Brandl
- SF  342  Coroutines via Enhanced Generators                      GvR, Eby
- SF  343  The "with" Statement                                    GvR, Coghlan
- SF  352  Required Superclass for Exceptions                      Cannon, GvR
- SF  353  Using ssize_t as the index type                         von Löwis
- SF  357  Allowing Any Object to be Used for Slicing              Oliphant
- SF  358  The "bytes" Object                                      Schemenauer, GvR
- SF  362  Function Signature Object                               Cannon, Seo, Selivanov, Hastings
- SF  366  Main module explicit relative imports                   Coghlan
- SF  370  Per user site-packages directory                        Heimes
- SF  371  Addition of the multiprocessing package to the ...      Noller, Oudkerk
- SF  372  Adding an ordered dictionary to collections             Ronacher, Hettinger
- SF  378  Format Specifier for Thousands Separator                Hettinger
- SF  380  Syntax for Delegating to a Subgenerator                 Ewing
- SF  383  Non-decodable Bytes in System Character Interfaces      v. Löwis
- SF  384  Defining a Stable ABI                                   v. Löwis
- SF  389  argparse - New Command Line Parsing Module              Bethard
- SF  391  Dictionary-Based Configuration For Logging              Sajip
- SF  393  Flexible String Representation                          v. Löwis
- SF  397  Python launcher for Windows                             Hammond, v. Löwis
- SF  405  Python Virtual Environments                             Meyer
- SF  409  Suppressing exception context                           Furman
- SF  412  Key-Sharing Dictionary                                  Shannon
- SF  414  Explicit Unicode Literal for Python 3.3                 Ronacher, Coghlan
- SF  415  Implement context suppression with exception attributes Peterson
- SF  417  Including mock in the Standard Library                  Foord
- SF  418  Add monotonic time, performance counter, and ...        Simpson, Jewett, Turnbull, Stinner
- SF  420  Implicit Namespace Packages                             Smith
- SF  421  Adding sys.implementation                               Snow
- SF  424  A method for exposing a length hint                     Gaynor
- SF  428  The pathlib module -- object-oriented filesystem paths  Pitrou
- SF  435  Adding an Enum type to the Python standard library      Warsaw, Bendersky, Furman
- SF  442  Safe object finalization                                Pitrou
- SF  443  Single-dispatch generic functions                       Langa
- SF  445  Add new APIs to customize Python memory allocators      Stinner
- SF  446  Make newly created file descriptors non-inheritable     Stinner
- SF  450  Adding A Statistics Module To The Standard Library      D'Aprano
- SF  451  A ModuleSpec Type for the Import System                 Snow
- SF  453  Explicit bootstrapping of pip in Python installations   Stufft, Coghlan
- SF  454  Add a new tracemalloc module to trace Python memory ... Stinner
- SF  456  Secure and interchangeable hash algorithm               Heimes
- SF  465  A dedicated infix operator for matrix multiplication    Smith
- SF  466  Network Security Enhancements for Python 2.7.x          Coghlan
- SF 3101  Advanced String Formatting                              Talin
- SF 3102  Keyword-Only Arguments                                  Talin
- SF 3104  Access to Names in Outer Scopes                         Yee
- SF 3105  Make print a function                                   Brandl
- SF 3106  Revamping dict.keys(), .values() and .items()           GvR
- SF 3107  Function Annotations                                    Winter, Lownds
- SF 3108  Standard Library Reorganization                         Cannon
- SF 3109  Raising Exceptions in Python 3000                       Winter
- SF 3110  Catching Exceptions in Python 3000                      Winter
- SF 3111  Simple input built-in in Python 3000                    Roberge
- SF 3112  Bytes literals in Python 3000                           Orendorff
- SF 3113  Removal of Tuple Parameter Unpacking                    Cannon
- SF 3114  Renaming iterator.next() to iterator.__next__()         Yee
- SF 3115  Metaclasses in Python 3000                              Talin
- SF 3116  New I/O                                                 Stutzbach, GvR, Verdone
- SF 3118  Revising the buffer protocol                            Oliphant, Banks
- SF 3119  Introducing Abstract Base Classes                       GvR, Talin
- SF 3120  Using UTF-8 as the default source encoding              von Löwis
- SF 3123  Making PyObject_HEAD conform to standard C              von Löwis
- SF 3127  Integer Literal Support and Syntax                      Maupin
- SF 3129  Class Decorators                                        Winter
- SF 3131  Supporting Non-ASCII Identifiers                        von Löwis
- SF 3132  Extended Iterable Unpacking                             Brandl
- SF 3134  Exception Chaining and Embedded Tracebacks              Yee
- SF 3135  New Super                                               Spealman, Delaney, Ryan
- SF 3137  Immutable Bytes and Mutable Buffer                      GvR
- SF 3138  String representation in Python 3000                    Ishimoto
- SF 3141  A Type Hierarchy for Numbers                            Yasskin
- SF 3144  IP Address Manipulation Library for the Python ...      Moody
- SF 3147  PYC Repository Directories                              Warsaw
- SF 3148  futures - execute computations asynchronously           Quinlan
- SF 3149  ABI version tagged .so files                            Warsaw
- SF 3151  Reworking the OS and IO exception hierarchy             Pitrou
- SF 3154  Pickle protocol version 4                               Pitrou
- SF 3155  Qualified name for classes and functions                Pitrou
- SF 3156  Asynchronous IO Support Rebooted: the "asyncio" Module  GvR
-
- Historical Meta-PEPs and Informational PEPs
-
- PF    2  Procedure for Adding New Modules                        Faassen
- PF   42  Feature Requests                                        Hylton
- IF  160  Python 1.6 Release Schedule                             Drake
- IF  200  Python 2.0 Release Schedule                             Hylton
- IF  226  Python 2.1 Release Schedule                             Hylton
- IF  251  Python 2.2 Release Schedule                             Warsaw, GvR
- IF  283  Python 2.3 Release Schedule                             GvR
- IF  320  Python 2.4 Release Schedule                             Warsaw, Hettinger, Baxter
- PF  347  Migrating the Python CVS to Subversion                  von Löwis
- IF  356  Python 2.5 Release Schedule                             Norwitz, GvR, Baxter
- PF  360  Externally Maintained Packages                          Cannon
- IF  361  Python 2.6 and 3.0 Release Schedule                     Norwitz, Warsaw
- PF  374  Choosing a distributed VCS for the Python project       Cannon, Turnbull, Vassalotti, Warsaw, Ochtman
- IF  375  Python 3.1 Release Schedule                             Peterson
- PF  385  Migrating from Subversion to Mercurial                  Ochtman, Pitrou, Brandl
- PA  438  Transitioning to release-file hosting on PyPI           Krekel, Meyer
- PA  449  Removal of the PyPI Mirror Auto Discovery and ...       Stufft
- PA  464  Removal of the PyPI Mirror Authenticity API             Stufft
- PF 3000  Python 3000                                             GvR
- PF 3002  Procedure for Backwards-Incompatible Changes            Bethard
- PF 3003  Python Language Moratorium                              Cannon, Noller, GvR
- PF 3099  Things that will Not Change in Python 3000              Brandl
- PF 3100  Miscellaneous Python 3.0 Plans                          Cannon
-
- Deferred PEPs
-
- SD  211  Adding A New Outer Product Operator                     Wilson
- SD  212  Loop Counter Iteration                                  Schneider-Kamp
- SD  213  Attribute Access Handlers                               Prescod
- SD  219  Stackless Python                                        McMillan
- SD  222  Web Library Enhancements                                Kuchling
- SD  225  Elementwise/Objectwise Operators                        Zhu, Lielens
- SD  233  Python Online Help                                      Prescod
- SD  262  A Database of Installed Python Packages                 Kuchling
- SD  267  Optimized Access to Module Namespaces                   Hylton
- SD  269  Pgen Module for Python                                  Riehl
- SD  280  Optimizing access to globals                            GvR
- SD  286  Enhanced Argument Tuples                                von Löwis
- SD  312  Simple Implicit Lambda                                  Suzi, Martelli
- SD  316  Programming by Contract for Python                      Way
- SD  323  Copyable Iterators                                      Martelli
- SD  337  Logging Usage in the Standard Library                   Dubner
- SD  349  Allow str() to return unicode strings                   Schemenauer
- SD  368  Standard image protocol and class                       Mastrodomenico
- ID  396  Module Version Numbers                                  Warsaw
- SD  400  Deprecate codecs.StreamReader and codecs.StreamWriter   Stinner
- SD  403  General purpose decorator clause (aka "@in" clause)     Coghlan
- PD  407  New release cycle and introducing long-term support ... Pitrou, Brandl, Warsaw
- SD  419  Protecting cleanup statements from interruptions        Colomiets
- SD  422  Simpler customisation of class creation                 Coghlan, Urban
- ID  423  Naming conventions and recipes related to packaging     Bryon
- ID  444  Python Web3 Interface                                   McDonough, Ronacher
- PD  462  Core development workflow automation for CPython        Coghlan
- PD  474  Creating forge.python.org                               Coghlan
- SD  628  Add ``math.tau``                                        Coghlan
- SD 3124  Overloading, Generic Functions, Interfaces, and ...     Eby
- SD 3143  Standard daemon process library                         Finney
- SD 3150  Statement local namespaces (aka "given" clause)         Coghlan
- SD 3152  Cofunctions                                             Ewing
-
- Abandoned, Withdrawn, and Rejected PEPs
-
- PW    3  Guidelines for Handling Bug Reports                     Hylton
- IS  102  Doing Python Micro Releases                             Baxter, Warsaw, GvR
- SR  204  Range Literals                                          Wouters
- IW  206  Python Advanced Library                                 Kuchling
- SW  209  Multi-dimensional Arrays                                Barrett, Oliphant
- SR  210  Decoupling the Interpreter Loop                         Ascher
- SS  215  String Interpolation                                    Yee
- IR  216  Docstring Format                                        Zadka
- IR  220  Coroutines, Generators, Continuations                   McMillan
- SR  224  Attribute Docstrings                                    Lemburg
- SW  228  Reworking Python's Numeric Model                        Zadka, GvR
- SR  231  __findattr__()                                          Warsaw
- SR  239  Adding a Rational Type to Python                        Craig, Zadka
- SR  240  Adding a Rational Literal to Python                     Craig, Zadka
- SR  242  Numeric Kinds                                           Dubois
- SW  243  Module Repository Upload Mechanism                      Reifschneider
- SR  244  The `directive' statement                               von Löwis
- SR  245  Python Interface Syntax                                 Pelletier
- SR  246  Object Adaptation                                       Martelli, Evans
- SR  254  Making Classes Look More Like Types                     GvR
- SR  256  Docstring Processing System Framework                   Goodger
- SR  258  Docutils Design Specification                           Goodger
- SR  259  Omit printing newline after newline                     GvR
- SR  265  Sorting Dictionaries by Value                           Griffin
- SW  266  Optimizing Global Variable/Attribute Access             Montanaro
- SR  268  Extended HTTP functionality and WebDAV                  Stein
- SR  270  uniq method for list objects                            Petrone
- SR  271  Prefixing sys.path by command line option               Giacometti
- SR  275  Switching on Multiple Values                            Lemburg
- SR  276  Simple Iterator for ints                                Althoff
- SR  281  Loop Counter Iteration with range and xrange            Hetland
- SR  284  Integer for-loops                                       Eppstein, Ewing
- SW  288  Generators Attributes and Exceptions                    Hettinger
- SR  294  Type Names in the types Module                          Tirosh
- SR  295  Interpretation of multiline string constants            Koltsov
- SW  296  Adding a bytes Object Type                              Gilbert
- SR  297  Support for System Upgrades                             Lemburg
- SW  298  The Locked Buffer Interface                             Heller
- SR  299  Special __main__() function in modules                  Epler
- SR  303  Extend divmod() for Multiple Divisors                   Bellman
- SW  304  Controlling Generation of Bytecode Files                Montanaro
- IW  306  How to Change Python's Grammar                          Hudson, Diederich, Coghlan, Peterson
- SR  310  Reliable Acquisition/Release Pairs                      Hudson, Moore
- SR  313  Adding Roman Numeral Literals to Python                 Meyer
- SR  315  Enhanced While Loop                                     Hettinger, Carroll
- SR  317  Eliminate Implicit Exception Instantiation              Taschuk
- SR  319  Python Synchronize/Asynchronize Block                   Pelletier
- SW  321  Date/Time Parsing and Formatting                        Kuchling
- SR  325  Resource-Release Support for Generators                 Pedroni
- SR  326  A Case for Top and Bottom Values                        Carlson, Reedy
- SR  329  Treating Builtins as Constants in the Standard Library  Hettinger
- SR  330  Python Bytecode Verification                            Pelletier
- SR  332  Byte vectors and String/Unicode Unification             Montanaro
- SW  334  Simple Coroutines via SuspendIteration                  Evans
- SR  335  Overloadable Boolean Operators                          Ewing
- SR  336  Make None Callable                                      McClelland
- IW  339  Design of the CPython Compiler                          Cannon
- SR  340  Anonymous Block Statements                              GvR
- SS  344  Exception Chaining and Embedded Tracebacks              Yee
- SW  346  User Defined ("``with``") Statements                    Coghlan
- SR  348  Exception Reorganization for Python 3.0                 Cannon
- IR  350  Codetags                                                Elliott
- SR  351  The freeze protocol                                     Warsaw
- SS  354  Enumerations in Python                                  Finney
- SR  355  Path - Object oriented filesystem paths                 Lindqvist
- SW  359  The "make" Statement                                    Bethard
- SR  363  Syntax For Dynamic Attribute Access                     North
- SW  364  Transitioning to the Py3K Standard Library              Warsaw
- SR  365  Adding the pkg_resources module                         Eby
- SS  367  New Super                                               Spealman, Delaney
- SW  369  Post import hooks                                       Heimes
- SR  377  Allow __enter__() methods to skip the statement body    Coghlan
- SW  379  Adding an Assignment Expression                         Whitley
- SR  382  Namespace Packages                                      v. Löwis
- SS  386  Changing the version comparison module in Distutils     Ziadé
- SR  390  Static metadata for Distutils                           Ziadé
- SW  395  Qualified Names for Modules                             Coghlan
- PR  401  BDFL Retirement                                         Warsaw, Cannon
- SR  402  Simplified Package Layout and Partitioning              Eby
- SW  406  Improved Encapsulation of Import State                  Coghlan, Slodkowicz
- SR  408  Standard library __preview__ package                    Coghlan, Bendersky
- SR  410  Use decimal.Decimal type for timestamps                 Stinner
- PW  413  Faster evolution of the Python Standard Library         Coghlan
- SR  416  Add a frozendict builtin type                           Stinner
- SS  433  Easier suppression of file descriptor inheritance       Stinner
- SR  437  A DSL for specifying signatures, annotations and ...    Krah
- SR  439  Inclusion of implicit pip bootstrap in Python ...       Jones
- SW  460  Add binary interpolation and formatting                 Pitrou
- SW  469  Migration of dict iteration code to Python 3            Coghlan
- SR  666  Reject Foolish Indentation                              Creighton
- SR  754  IEEE 754 Floating Point Special Values                  Warnes
- PW 3001  Procedure for reviewing and improving standard ...      Brandl
- SR 3103  A Switch/Case Statement                                 GvR
- SR 3117  Postfix type declarations                               Brandl
- SR 3122  Delineation of the main module                          Cannon
- SR 3125  Remove Backslash Continuation                           Jewett
- SR 3126  Remove Implicit String Concatenation                    Jewett, Hettinger
- SR 3128  BList: A Faster List-like Type                          Stutzbach
- SR 3130  Access to Current Module/Class/Function                 Jewett
- SR 3133  Introducing Roles                                       Winter
- SR 3136  Labeled break and continue                              Chisholm
- SR 3139  Cleaning out sys and the "interpreter" module           Peterson
- SR 3140  str(container) should call str(item), not repr(item)    Broytmann, Jewett
- SR 3142  Add a "while" clause to generator expressions           Britton
- SW 3145  Asynchronous I/O For subprocess.Popen                   Pruitt, McCreary, Carlson
- SW 3146  Merging Unladen Swallow into CPython                    Winter, Yasskin, Kleckner
- SS 3153  Asynchronous IO support                                 Houtven
-
-
-
-

Numerical Index

-
-     num  title                                                   owner
-     ---  -----                                                   -----
- P     1  PEP Purpose and Guidelines                              Warsaw, Hylton, Goodger, Coghlan
- PF    2  Procedure for Adding New Modules                        Faassen
- PW    3  Guidelines for Handling Bug Reports                     Hylton
- P     4  Deprecation of Standard Modules                         von Löwis
- P     5  Guidelines for Language Evolution                       Prescod
- P     6  Bug Fix Releases                                        Aahz, Baxter
- P     7  Style Guide for C Code                                  GvR
- P     8  Style Guide for Python Code                             GvR, Warsaw, Coghlan
- P     9  Sample Plaintext PEP Template                           Warsaw
- P    10  Voting Guidelines                                       Warsaw
- P    11  Removing support for little used platforms              von Löwis
- P    12  Sample reStructuredText PEP Template                    Goodger, Warsaw
-
- I    20  The Zen of Python                                       Peters
-
- PF   42  Feature Requests                                        Hylton
-
- SF  100  Python Unicode Integration                              Lemburg
- I   101  Doing Python Releases 101                               Warsaw, GvR
- IS  102  Doing Python Micro Releases                             Baxter, Warsaw, GvR
-
- IF  160  Python 1.6 Release Schedule                             Drake
-
- IF  200  Python 2.0 Release Schedule                             Hylton
- SF  201  Lockstep Iteration                                      Warsaw
- SF  202  List Comprehensions                                     Warsaw
- SF  203  Augmented Assignments                                   Wouters
- SR  204  Range Literals                                          Wouters
- SF  205  Weak References                                         Drake
- IW  206  Python Advanced Library                                 Kuchling
- SF  207  Rich Comparisons                                        GvR, Ascher
- SF  208  Reworking the Coercion Model                            Schemenauer, Lemburg
- SW  209  Multi-dimensional Arrays                                Barrett, Oliphant
- SR  210  Decoupling the Interpreter Loop                         Ascher
- SD  211  Adding A New Outer Product Operator                     Wilson
- SD  212  Loop Counter Iteration                                  Schneider-Kamp
- SD  213  Attribute Access Handlers                               Prescod
- SF  214  Extended Print Statement                                Warsaw
- SS  215  String Interpolation                                    Yee
- IR  216  Docstring Format                                        Zadka
- SF  217  Display Hook for Interactive Use                        Zadka
- SF  218  Adding a Built-In Set Object Type                       Wilson, Hettinger
- SD  219  Stackless Python                                        McMillan
- IR  220  Coroutines, Generators, Continuations                   McMillan
- SF  221  Import As                                               Wouters
- SD  222  Web Library Enhancements                                Kuchling
- SF  223  Change the Meaning of \x Escapes                        Peters
- SR  224  Attribute Docstrings                                    Lemburg
- SD  225  Elementwise/Objectwise Operators                        Zhu, Lielens
- IF  226  Python 2.1 Release Schedule                             Hylton
- SF  227  Statically Nested Scopes                                Hylton
- SW  228  Reworking Python's Numeric Model                        Zadka, GvR
- SF  229  Using Distutils to Build Python                         Kuchling
- SF  230  Warning Framework                                       GvR
- SR  231  __findattr__()                                          Warsaw
- SF  232  Function Attributes                                     Warsaw
- SD  233  Python Online Help                                      Prescod
- SF  234  Iterators                                               Yee, GvR
- SF  235  Import on Case-Insensitive Platforms                    Peters
- SF  236  Back to the __future__                                  Peters
- SF  237  Unifying Long Integers and Integers                     Zadka, GvR
- SF  238  Changing the Division Operator                          Zadka, GvR
- SR  239  Adding a Rational Type to Python                        Craig, Zadka
- SR  240  Adding a Rational Literal to Python                     Craig, Zadka
- SF  241  Metadata for Python Software Packages                   Kuchling
- SR  242  Numeric Kinds                                           Dubois
- SW  243  Module Repository Upload Mechanism                      Reifschneider
- SR  244  The `directive' statement                               von Löwis
- SR  245  Python Interface Syntax                                 Pelletier
- SR  246  Object Adaptation                                       Martelli, Evans
- IF  247  API for Cryptographic Hash Functions                    Kuchling
- IF  248  Python Database API Specification v1.0                  Lemburg
- IF  249  Python Database API Specification v2.0                  Lemburg
- SF  250  Using site-packages on Windows                          Moore
- IF  251  Python 2.2 Release Schedule                             Warsaw, GvR
- SF  252  Making Types Look More Like Classes                     GvR
- SF  253  Subtyping Built-in Types                                GvR
- SR  254  Making Classes Look More Like Types                     GvR
- SF  255  Simple Generators                                       Schemenauer, Peters, Hetland
- SR  256  Docstring Processing System Framework                   Goodger
- I   257  Docstring Conventions                                   Goodger, GvR
- SR  258  Docutils Design Specification                           Goodger
- SR  259  Omit printing newline after newline                     GvR
- SF  260  Simplify xrange()                                       GvR
- SF  261  Support for "wide" Unicode characters                   Prescod
- SD  262  A Database of Installed Python Packages                 Kuchling
- SF  263  Defining Python Source Code Encodings                   Lemburg, von Löwis
- SF  264  Future statements in simulated shells                   Hudson
- SR  265  Sorting Dictionaries by Value                           Griffin
- SW  266  Optimizing Global Variable/Attribute Access             Montanaro
- SD  267  Optimized Access to Module Namespaces                   Hylton
- SR  268  Extended HTTP functionality and WebDAV                  Stein
- SD  269  Pgen Module for Python                                  Riehl
- SR  270  uniq method for list objects                            Petrone
- SR  271  Prefixing sys.path by command line option               Giacometti
- IF  272  API for Block Encryption Algorithms v1.0                Kuchling
- SF  273  Import Modules from Zip Archives                        Ahlstrom
- SF  274  Dict Comprehensions                                     Warsaw
- SR  275  Switching on Multiple Values                            Lemburg
- SR  276  Simple Iterator for ints                                Althoff
- SF  277  Unicode file name support for Windows NT                Hodgson
- SF  278  Universal Newline Support                               Jansen
- SF  279  The enumerate() built-in function                       Hettinger
- SD  280  Optimizing access to globals                            GvR
- SR  281  Loop Counter Iteration with range and xrange            Hetland
- SF  282  A Logging System                                        Sajip, Mick
- IF  283  Python 2.3 Release Schedule                             GvR
- SR  284  Integer for-loops                                       Eppstein, Ewing
- SF  285  Adding a bool type                                      GvR
- SD  286  Enhanced Argument Tuples                                von Löwis
- I   287  reStructuredText Docstring Format                       Goodger
- SW  288  Generators Attributes and Exceptions                    Hettinger
- SF  289  Generator Expressions                                   Hettinger
- I   290  Code Migration and Modernization                        Hettinger
- IF  291  Backward Compatibility for the Python 2 Standard ...    Norwitz
- SF  292  Simpler String Substitutions                            Warsaw
- SF  293  Codec Error Handling Callbacks                          Dörwald
- SR  294  Type Names in the types Module                          Tirosh
- SR  295  Interpretation of multiline string constants            Koltsov
- SW  296  Adding a bytes Object Type                              Gilbert
- SR  297  Support for System Upgrades                             Lemburg
- SW  298  The Locked Buffer Interface                             Heller
- SR  299  Special __main__() function in modules                  Epler
-
- SF  301  Package Index and Metadata for Distutils                Jones
- SF  302  New Import Hooks                                        JvR, Moore
- SR  303  Extend divmod() for Multiple Divisors                   Bellman
- SW  304  Controlling Generation of Bytecode Files                Montanaro
- SF  305  CSV File API                                            Altis, Cole, McNamara, Montanaro, Wells
- IW  306  How to Change Python's Grammar                          Hudson, Diederich, Coghlan, Peterson
- SF  307  Extensions to the pickle protocol                       GvR, Peters
- SF  308  Conditional Expressions                                 GvR, Hettinger
- SF  309  Partial Function Application                            Harris
- SR  310  Reliable Acquisition/Release Pairs                      Hudson, Moore
- SF  311  Simplified Global Interpreter Lock Acquisition for ...  Hammond
- SD  312  Simple Implicit Lambda                                  Suzi, Martelli
- SR  313  Adding Roman Numeral Literals to Python                 Meyer
- SF  314  Metadata for Python Software Packages v1.1              Kuchling, Jones
- SR  315  Enhanced While Loop                                     Hettinger, Carroll
- SD  316  Programming by Contract for Python                      Way
- SR  317  Eliminate Implicit Exception Instantiation              Taschuk
- SF  318  Decorators for Functions and Methods                    Smith
- SR  319  Python Synchronize/Asynchronize Block                   Pelletier
- IF  320  Python 2.4 Release Schedule                             Warsaw, Hettinger, Baxter
- SW  321  Date/Time Parsing and Formatting                        Kuchling
- SF  322  Reverse Iteration                                       Hettinger
- SD  323  Copyable Iterators                                      Martelli
- SF  324  subprocess - New process module                         Astrand
- SR  325  Resource-Release Support for Generators                 Pedroni
- SR  326  A Case for Top and Bottom Values                        Carlson, Reedy
- SF  327  Decimal Data Type                                       Batista
- SF  328  Imports: Multi-Line and Absolute/Relative               Aahz
- SR  329  Treating Builtins as Constants in the Standard Library  Hettinger
- SR  330  Python Bytecode Verification                            Pelletier
- SF  331  Locale-Independent Float/String Conversions             Reis
- SR  332  Byte vectors and String/Unicode Unification             Montanaro
- IF  333  Python Web Server Gateway Interface v1.0                Eby
- SW  334  Simple Coroutines via SuspendIteration                  Evans
- SR  335  Overloadable Boolean Operators                          Ewing
- SR  336  Make None Callable                                      McClelland
- SD  337  Logging Usage in the Standard Library                   Dubner
- SF  338  Executing modules as scripts                            Coghlan
- IW  339  Design of the CPython Compiler                          Cannon
- SR  340  Anonymous Block Statements                              GvR
- SF  341  Unifying try-except and try-finally                     Brandl
- SF  342  Coroutines via Enhanced Generators                      GvR, Eby
- SF  343  The "with" Statement                                    GvR, Coghlan
- SS  344  Exception Chaining and Embedded Tracebacks              Yee
- SA  345  Metadata for Python Software Packages 1.2               Jones
- SW  346  User Defined ("``with``") Statements                    Coghlan
- PF  347  Migrating the Python CVS to Subversion                  von Löwis
- SR  348  Exception Reorganization for Python 3.0                 Cannon
- SD  349  Allow str() to return unicode strings                   Schemenauer
- IR  350  Codetags                                                Elliott
- SR  351  The freeze protocol                                     Warsaw
- SF  352  Required Superclass for Exceptions                      Cannon, GvR
- SF  353  Using ssize_t as the index type                         von Löwis
- SS  354  Enumerations in Python                                  Finney
- SR  355  Path - Object oriented filesystem paths                 Lindqvist
- IF  356  Python 2.5 Release Schedule                             Norwitz, GvR, Baxter
- SF  357  Allowing Any Object to be Used for Slicing              Oliphant
- SF  358  The "bytes" Object                                      Schemenauer, GvR
- SW  359  The "make" Statement                                    Bethard
- PF  360  Externally Maintained Packages                          Cannon
- IF  361  Python 2.6 and 3.0 Release Schedule                     Norwitz, Warsaw
- SF  362  Function Signature Object                               Cannon, Seo, Selivanov, Hastings
- SR  363  Syntax For Dynamic Attribute Access                     North
- SW  364  Transitioning to the Py3K Standard Library              Warsaw
- SR  365  Adding the pkg_resources module                         Eby
- SF  366  Main module explicit relative imports                   Coghlan
- SS  367  New Super                                               Spealman, Delaney
- SD  368  Standard image protocol and class                       Mastrodomenico
- SW  369  Post import hooks                                       Heimes
- SF  370  Per user site-packages directory                        Heimes
- SF  371  Addition of the multiprocessing package to the ...      Noller, Oudkerk
- SF  372  Adding an ordered dictionary to collections             Ronacher, Hettinger
- I   373  Python 2.7 Release Schedule                             Peterson
- PF  374  Choosing a distributed VCS for the Python project       Cannon, Turnbull, Vassalotti, Warsaw, Ochtman
- IF  375  Python 3.1 Release Schedule                             Peterson
- SA  376  Database of Installed Python Distributions              Ziadé
- SR  377  Allow __enter__() methods to skip the statement body    Coghlan
- SF  378  Format Specifier for Thousands Separator                Hettinger
- SW  379  Adding an Assignment Expression                         Whitley
- SF  380  Syntax for Delegating to a Subgenerator                 Ewing
- S   381  Mirroring infrastructure for PyPI                       Ziadé, v. Löwis
- SR  382  Namespace Packages                                      v. Löwis
- SF  383  Non-decodable Bytes in System Character Interfaces      v. Löwis
- SF  384  Defining a Stable ABI                                   v. Löwis
- PF  385  Migrating from Subversion to Mercurial                  Ochtman, Pitrou, Brandl
- SS  386  Changing the version comparison module in Distutils     Ziadé
- P   387  Backwards Compatibility Policy                          Peterson
-
- SF  389  argparse - New Command Line Parsing Module              Bethard
- SR  390  Static metadata for Distutils                           Ziadé
- SF  391  Dictionary-Based Configuration For Logging              Sajip
- I   392  Python 3.2 Release Schedule                             Brandl
- SF  393  Flexible String Representation                          v. Löwis
- I   394  The "python" Command on Unix-Like Systems               Staley, Coghlan
- SW  395  Qualified Names for Modules                             Coghlan
- ID  396  Module Version Numbers                                  Warsaw
- SF  397  Python launcher for Windows                             Hammond, v. Löwis
- I   398  Python 3.3 Release Schedule                             Brandl
- IF  399  Pure Python/C Accelerator Module Compatibility ...      Cannon
- SD  400  Deprecate codecs.StreamReader and codecs.StreamWriter   Stinner
- PR  401  BDFL Retirement                                         Warsaw, Cannon
- SR  402  Simplified Package Layout and Partitioning              Eby
- SD  403  General purpose decorator clause (aka "@in" clause)     Coghlan
- IF  404  Python 2.8 Un-release Schedule                          Warsaw
- SF  405  Python Virtual Environments                             Meyer
- SW  406  Improved Encapsulation of Import State                  Coghlan, Slodkowicz
- PD  407  New release cycle and introducing long-term support ... Pitrou, Brandl, Warsaw
- SR  408  Standard library __preview__ package                    Coghlan, Bendersky
- SF  409  Suppressing exception context                           Furman
- SR  410  Use decimal.Decimal type for timestamps                 Stinner
- IA  411  Provisional packages in the Python standard library     Coghlan, Bendersky
- SF  412  Key-Sharing Dictionary                                  Shannon
- PW  413  Faster evolution of the Python Standard Library         Coghlan
- SF  414  Explicit Unicode Literal for Python 3.3                 Ronacher, Coghlan
- SF  415  Implement context suppression with exception attributes Peterson
- SR  416  Add a frozendict builtin type                           Stinner
- SF  417  Including mock in the Standard Library                  Foord
- SF  418  Add monotonic time, performance counter, and ...        Simpson, Jewett, Turnbull, Stinner
- SD  419  Protecting cleanup statements from interruptions        Colomiets
- SF  420  Implicit Namespace Packages                             Smith
- SF  421  Adding sys.implementation                               Snow
- SD  422  Simpler customisation of class creation                 Coghlan, Urban
- ID  423  Naming conventions and recipes related to packaging     Bryon
- SF  424  A method for exposing a length hint                     Gaynor
- SA  425  Compatibility Tags for Built Distributions              Holth
- S   426  Metadata for Python Software Packages 2.0               Coghlan, Holth, Stufft
- SA  427  The Wheel Binary Package Format 1.0                     Holth
- SF  428  The pathlib module -- object-oriented filesystem paths  Pitrou
- I   429  Python 3.4 Release Schedule                             Hastings
- IF  430  Migrating to Python 3 as the default online ...         Coghlan
- S   431  Time zone support improvements                          Regebro
- S   432  Simplifying the CPython startup sequence                Coghlan
- SS  433  Easier suppression of file descriptor inheritance       Stinner
- I   434  IDLE Enhancement Exception for All Branches             Rovito, Reedy
- SF  435  Adding an Enum type to the Python standard library      Warsaw, Bendersky, Furman
- S   436  The Argument Clinic DSL                                 Hastings
- SR  437  A DSL for specifying signatures, annotations and ...    Krah
- PA  438  Transitioning to release-file hosting on PyPI           Krekel, Meyer
- SR  439  Inclusion of implicit pip bootstrap in Python ...       Jones
- IA  440  Version Identification and Dependency Specification     Coghlan, Stufft
- S   441  Improving Python ZIP Application Support                Holth
- SF  442  Safe object finalization                                Pitrou
- SF  443  Single-dispatch generic functions                       Langa
- ID  444  Python Web3 Interface                                   McDonough, Ronacher
- SF  445  Add new APIs to customize Python memory allocators      Stinner
- SF  446  Make newly created file descriptors non-inheritable     Stinner
- S   447  Add __getdescriptor__ method to metaclass               Oussoren
- S   448  Additional Unpacking Generalizations                    Landau
- PA  449  Removal of the PyPI Mirror Auto Discovery and ...       Stufft
- SF  450  Adding A Statistics Module To The Standard Library      D'Aprano
- SF  451  A ModuleSpec Type for the Import System                 Snow
- I   452  API for Cryptographic Hash Functions v2.0               Kuchling, Heimes
- SF  453  Explicit bootstrapping of pip in Python installations   Stufft, Coghlan
- SF  454  Add a new tracemalloc module to trace Python memory ... Stinner
- S   455  Adding a key-transforming dictionary to collections     Pitrou
- SF  456  Secure and interchangeable hash algorithm               Heimes
- I   457  Syntax For Positional-Only Parameters                   Hastings
- S   458  Surviving a Compromise of PyPI                          Kuppusamy, Stufft, Cappos
- S   459  Standard Metadata Extensions for Python Software ...    Coghlan
- SW  460  Add binary interpolation and formatting                 Pitrou
- SA  461  Adding % formatting to bytes and bytearray              Furman
- PD  462  Core development workflow automation for CPython        Coghlan
- S   463  Exception-catching expressions                          Angelico
- PA  464  Removal of the PyPI Mirror Authenticity API             Stufft
- SF  465  A dedicated infix operator for matrix multiplication    Smith
- SF  466  Network Security Enhancements for Python 2.7.x          Coghlan
- S   467  Minor API improvements for binary sequences             Coghlan
- S   468  Preserving the order of \*\*kwargs in a function.       Snow
- SW  469  Migration of dict iteration code to Python 3            Coghlan
- P   470  Using Multi Index Support for External to PyPI ...      Stufft
- SA  471  os.scandir() function -- a better and faster ...        Hoyt
- S   472  Support for indexing with keyword arguments             Borini, Martinot-Lagarde
- S   473  Adding structured data to built-in exceptions           Kreft
- PD  474  Creating forge.python.org                               Coghlan
- S   475  Retry system calls failing with EINTR                   Natali, Stinner
- S   476  Enabling certificate verification by default for ...    Gaynor
- SA  477  Backport ensurepip (PEP 453) to Python 2.7              Stufft, Coghlan
- I   478  Python 3.5 Release Schedule                             Hastings
-
- SD  628  Add ``math.tau``                                        Coghlan
-
- SR  666  Reject Foolish Indentation                              Creighton
-
- SR  754  IEEE 754 Floating Point Special Values                  Warnes
-
- PF 3000  Python 3000                                             GvR
- PW 3001  Procedure for reviewing and improving standard ...      Brandl
- PF 3002  Procedure for Backwards-Incompatible Changes            Bethard
- PF 3003  Python Language Moratorium                              Cannon, Noller, GvR
-
- PF 3099  Things that will Not Change in Python 3000              Brandl
- PF 3100  Miscellaneous Python 3.0 Plans                          Cannon
- SF 3101  Advanced String Formatting                              Talin
- SF 3102  Keyword-Only Arguments                                  Talin
- SR 3103  A Switch/Case Statement                                 GvR
- SF 3104  Access to Names in Outer Scopes                         Yee
- SF 3105  Make print a function                                   Brandl
- SF 3106  Revamping dict.keys(), .values() and .items()           GvR
- SF 3107  Function Annotations                                    Winter, Lownds
- SF 3108  Standard Library Reorganization                         Cannon
- SF 3109  Raising Exceptions in Python 3000                       Winter
- SF 3110  Catching Exceptions in Python 3000                      Winter
- SF 3111  Simple input built-in in Python 3000                    Roberge
- SF 3112  Bytes literals in Python 3000                           Orendorff
- SF 3113  Removal of Tuple Parameter Unpacking                    Cannon
- SF 3114  Renaming iterator.next() to iterator.__next__()         Yee
- SF 3115  Metaclasses in Python 3000                              Talin
- SF 3116  New I/O                                                 Stutzbach, GvR, Verdone
- SR 3117  Postfix type declarations                               Brandl
- SF 3118  Revising the buffer protocol                            Oliphant, Banks
- SF 3119  Introducing Abstract Base Classes                       GvR, Talin
- SF 3120  Using UTF-8 as the default source encoding              von Löwis
- SA 3121  Extension Module Initialization and Finalization        von Löwis
- SR 3122  Delineation of the main module                          Cannon
- SF 3123  Making PyObject_HEAD conform to standard C              von Löwis
- SD 3124  Overloading, Generic Functions, Interfaces, and ...     Eby
- SR 3125  Remove Backslash Continuation                           Jewett
- SR 3126  Remove Implicit String Concatenation                    Jewett, Hettinger
- SF 3127  Integer Literal Support and Syntax                      Maupin
- SR 3128  BList: A Faster List-like Type                          Stutzbach
- SF 3129  Class Decorators                                        Winter
- SR 3130  Access to Current Module/Class/Function                 Jewett
- SF 3131  Supporting Non-ASCII Identifiers                        von Löwis
- SF 3132  Extended Iterable Unpacking                             Brandl
- SR 3133  Introducing Roles                                       Winter
- SF 3134  Exception Chaining and Embedded Tracebacks              Yee
- SF 3135  New Super                                               Spealman, Delaney, Ryan
- SR 3136  Labeled break and continue                              Chisholm
- SF 3137  Immutable Bytes and Mutable Buffer                      GvR
- SF 3138  String representation in Python 3000                    Ishimoto
- SR 3139  Cleaning out sys and the "interpreter" module           Peterson
- SR 3140  str(container) should call str(item), not repr(item)    Broytmann, Jewett
- SF 3141  A Type Hierarchy for Numbers                            Yasskin
- SR 3142  Add a "while" clause to generator expressions           Britton
- SD 3143  Standard daemon process library                         Finney
- SF 3144  IP Address Manipulation Library for the Python ...      Moody
- SW 3145  Asynchronous I/O For subprocess.Popen                   Pruitt, McCreary, Carlson
- SW 3146  Merging Unladen Swallow into CPython                    Winter, Yasskin, Kleckner
- SF 3147  PYC Repository Directories                              Warsaw
- SF 3148  futures - execute computations asynchronously           Quinlan
- SF 3149  ABI version tagged .so files                            Warsaw
- SD 3150  Statement local namespaces (aka "given" clause)         Coghlan
- SF 3151  Reworking the OS and IO exception hierarchy             Pitrou
- SD 3152  Cofunctions                                             Ewing
- SS 3153  Asynchronous IO support                                 Houtven
- SF 3154  Pickle protocol version 4                               Pitrou
- SF 3155  Qualified name for classes and functions                Pitrou
- SF 3156  Asynchronous IO Support Rebooted: the "asyncio" Module  GvR
-
- IF 3333  Python Web Server Gateway Interface v1.0.1              Eby
-
-
-
-

Reserved PEP Numbers

-
-     num  title                                                   owner
-     ---  -----                                                   -----
-     801  RESERVED                                                Warsaw
-
-
-
-

Key

-
-    S - Standards Track PEP
-    I - Informational PEP
-    P - Process PEP
-
-    A - Accepted proposal
-    R - Rejected proposal
-    W - Withdrawn proposal
-    D - Deferred proposal
-    F - Final proposal
-    A - Active proposal
-    D - Draft proposal
-    S - Superseded proposal
-
-
-
-

Owners

-
-    name                         email address
-    ----                         -------------
-    Aahz                         aahz at pythoncraft.com
-    Ahlstrom, James C.           jim at interet.com
-    Althoff, Jim                 james_althoff at i2.com
-    Altis, Kevin                 altis at semi-retired.com
-    Angelico, Chris              rosuav at gmail.com
-    Ascher, David                davida at activestate.com
-    Astrand, Peter               astrand at lysator.liu.se
-    Banks, Carl                  pythondev at aerojockey.com
-    Barrett, Paul                barrett at stsci.edu
-    Batista, Facundo             facundo at taniquetil.com.ar
-    Baxter, Anthony              anthony at interlink.com.au
-    Bellman, Thomas              bellman+pep-divmod@lysator.liu.se
-    Bendersky, Eli               eliben at gmail.com
-    Bethard, Steven              steven.bethard at gmail.com
-    Borini, Stefano              
-    Brandl, Georg                georg at python.org
-    Britton, Gerald              gerald.britton at gmail.com
-    Broytmann, Oleg              phd at phd.pp.ru
-    Bryon, Benoit                benoit at marmelune.net
-    Cannon, Brett                brett at python.org
-    Cappos, Justin               jcappos at poly.edu
-    Carlson, Josiah              jcarlson at uci.edu
-    Carroll,         W Isaac     icarroll at pobox.com
-    Chisholm, Matt               matt-python at theory.org
-    Coghlan, Nick                ncoghlan at gmail.com
-    Cole, Dave                   djc at object-craft.com.au
-    Colomiets, Paul              paul at colomiets.name
-    Craig, Christopher A.        python-pep at ccraig.org
-    Creighton, Laura             lac at strakt.com
-    D'Aprano, Steven             steve at pearwood.info
-    Delaney, Tim                 timothy.c.delaney at gmail.com
-    Diederich, Jack              jackdied at gmail.com
-    Dörwald, Walter              walter at livinglogic.de
-    Drake, Fred L., Jr.          fdrake at acm.org
-    Dubner, Michael P.           dubnerm at mindless.com
-    Dubois, Paul F.              paul at pfdubois.com
-    Eby, P.J.                    pje at telecommunity.com
-    Eby, Phillip J.              pje at telecommunity.com
-    Elliott, Micah               mde at tracos.org
-    Epler, Jeff                  jepler at unpythonic.net
-    Eppstein, David              eppstein at ics.uci.edu
-    Evans, Clark C.              cce at clarkevans.com
-    Ewing, Gregory               greg.ewing at canterbury.ac.nz
-    Ewing, Greg                  greg.ewing at canterbury.ac.nz
-    Faassen, Martijn             faassen at infrae.com
-    Finney, Ben                  ben+python@benfinney.id.au
-    Foord, Michael               michael at python.org
-    Furman, Ethan                ethan at stoneleaf.us
-    Gaynor, Alex                 alex.gaynor at gmail.com
-    Giacometti, Frédéric B.      fred at arakne.com
-    Gilbert, Scott               xscottg at yahoo.com
-    Goodger, David               goodger at python.org
-    Griffin, Grant               g2 at iowegian.com
-    Hammond, Mark                mhammond at skippinet.com.au
-    Harris, Peter                scav at blueyonder.co.uk
-    Hastings, Larry              larry at hastings.org
-    Heimes, Christian            christian at python.org
-    Heller, Thomas               theller at python.net
-    Hetland, Magnus Lie          magnus at hetland.org
-    Hettinger, Raymond           python at rcn.com
-    Hodgson, Neil                neilh at scintilla.org
-    Holth, Daniel                dholth at gmail.com
-    Houtven, Laurens Van         _ at lvh.cc
-    Hoyt, Ben                    benhoyt at gmail.com
-    Hudson, Michael              mwh at python.net
-    Hylton, Jeremy               jeremy at alum.mit.edu
-    Ishimoto, Atsuo              ishimoto--at--gembook.org
-    Jansen, Jack                 jack at cwi.nl
-    Jewett, Jim J.               jimjjewett at gmail.com
-    Jewett, Jim                  jimjjewett at gmail.com
-    Jones, Richard               richard at python.org
-    Kleckner, Reid               rnk at mit.edu
-    Koltsov, Stepan              yozh at mx1.ru
-    Krah, Stefan                 skrah at bytereef.org
-    Kreft, Sebastian             skreft at deezer.com
-    Krekel, Holger               holger at merlinux.eu
-    Kuchling, A.M.               amk at amk.ca
-    Kuppusamy, Trishank Karthik  tk47 at students.poly.edu
-    Landau, Joshua               joshua at landau.ws
-    Langa, Łukasz                lukasz at langa.pl
-    Lemburg, Marc-André          mal at lemburg.com
-    Lielens, Gregory             gregory.lielens at fft.be
-    Lindqvist, Björn             bjourne at gmail.com
-    von Löwis, Martin            martin at v.loewis.de
-    v. Löwis, Martin             martin at v.loewis.de
-    Lownds, Tony                 tony at lownds.com
-    Martelli, Alex               aleaxit at gmail.com
-    Martinot-Lagarde, Joseph     
-    Mastrodomenico, Lino         l.mastrodomenico at gmail.com
-    Maupin, Patrick              pmaupin at gmail.com
-    McClelland, Andrew           eternalsquire at comcast.net
-    McCreary, Charles R.         
-    McDonough, Chris             chrism at plope.com
-    McMillan, Gordon             gmcm at hypernet.com
-    McNamara, Andrew             andrewm at object-craft.com.au
-    Meyer, Mike                  mwm at mired.org
-    Meyer, Carl                  carl at oddbird.net
-    Mick, Trent                  trentm at activestate.com
-    Montanaro, Skip              skip at pobox.com
-    Moody, Peter                 pmoody at google.com
-    Moore, Paul                  gustav at morpheus.demon.co.uk
-    Natali, Charles-François     cf.natali at gmail.com
-    Noller, Jesse                jnoller at gmail.com
-    North, Ben                   ben at redfrontdoor.org
-    Norwitz, Neal                nnorwitz at gmail.com
-    Ochtman, Dirkjan             dirkjan at ochtman.nl
-    Oliphant, Travis             oliphant at ee.byu.edu
-    Orendorff, Jason             jason.orendorff at gmail.com
-    Oudkerk, Richard             r.m.oudkerk at googlemail.com
-    Oussoren, Ronald             ronaldoussoren at mac.com
-    Pedroni, Samuele             pedronis at python.org
-    Pelletier, Michel            michel at users.sourceforge.net
-    Peters, Tim                  tim at zope.com
-    Peterson, Benjamin           benjamin at python.org
-    Petrone, Jason               jp at demonseed.net
-    Pitrou, Antoine              solipsis at pitrou.net
-    Prescod, Paul                paul at prescod.net
-    Pruitt, (James) Eric         
-    Quinlan, Brian               brian at sweetapp.com
-    Reedy, Terry                 tjreedy at udel.edu
-    Regebro, Lennart             regebro at gmail.com
-    Reifschneider, Sean          jafo-pep at tummy.com
-    Reis, Christian R.           kiko at async.com.br
-    Riehl, Jonathan              jriehl at spaceship.com
-    Roberge, Andre               andre.roberge at gmail.com 
-    Ronacher, Armin              armin.ronacher at active-4.com
-    van Rossum, Guido (GvR)      guido at python.org
-    van Rossum, Just (JvR)       just at letterror.com
-    Rovito, Todd                 rovitotv at gmail.com
-    Ryan, Lie                    lie.1296 at gmail.com
-    Sajip, Vinay                 vinay_sajip at red-dove.com
-    Schemenauer, Neil            nas at arctrix.com
-    Schneider-Kamp, Peter        nowonder at nowonder.de
-    Selivanov, Yury              yselivanov at sprymix.com
-    Seo, Jiwon                   seojiwon at gmail.com
-    Shannon, Mark                mark at hotpy.org
-    Simpson, Cameron             cs at zip.com.au
-    Slodkowicz, Greg             jergosh at gmail.com
-    Smith, Nathaniel J.          njs at pobox.com
-    Smith, Kevin D.              kevin.smith at themorgue.org
-    Smith, Eric V.               eric at trueblade.com
-    Snow, Eric                   ericsnowcurrently at gmail.com
-    Spealman, Calvin             ironfroggy at gmail.com
-    Staley, Kerrick              mail at kerrickstaley.com
-    Stein, Greg                  gstein at lyra.org
-    Stinner, Victor              victor.stinner at gmail.com
-    Stufft, Donald               donald at stufft.io
-    Stutzbach, Daniel            daniel at stutzbachenterprises.com
-    Suzi, Roman                  rnd at onego.ru
-    Talin                        talin at acm.org
-    Taschuk, Steven              staschuk at telusplanet.net
-    Tirosh, Oren                 oren at hishome.net
-    Turnbull, Stephen J.         stephen at xemacs.org
-    Urban, Daniel                urban.dani+py@gmail.com
-    Vassalotti, Alexandre        alexandre at peadrop.com
-    Verdone, Mike                mike.verdone at gmail.com
-    Warnes, Gregory R.           gregory_r_warnes at groton.pfizer.com
-    Warsaw, Barry                barry at python.org
-    Way, Terence                 terry at wayforward.net
-    Wells, Cliff                 logiplexsoftware at earthlink.net
-    Whitley, Jervis              jervisau at gmail.com
-    Wilson, Greg                 gvwilson at ddj.com
-    Winter, Collin               collinwinter at google.com
-    Wouters, Thomas              thomas at python.org
-    Yasskin, Jeffrey             jyasskin at google.com
-    Yee, Ka-Ping                 ping at zesty.ca
-    Zadka, Moshe                 moshez at zadka.site.co.il
-    Zhu, Huaiyu                  hzhu at users.sourceforge.net
-    Ziadé, Tarek                 tarek at ziade.org
-
-
-
-

References

-
-    [1] PEP 1: PEP Purpose and Guidelines
-    [2] View PEP history online
-        http://hg.python.org/peps/
-
-
-
- - diff --git a/peps/tests/peps/pep-0012.html b/peps/tests/peps/pep-0012.html deleted file mode 100644 index e341e82f5..000000000 --- a/peps/tests/peps/pep-0012.html +++ /dev/null @@ -1,53 +0,0 @@ - - --- - - - - - - - - - - - - - - - - - -
PEP:12
Title:Sample reStructuredText PEP Template
Author:David Goodger <goodger at python.org>, -Barry Warsaw <barry at python.org>
Status:Active
Type:Process
Content-Type:text/x-rst
Created:05-Aug-2002
Post-History:30-Aug-2002
-
-
-

Contents

- -
-
-

Abstract

-

This PEP provides a boilerplate or sample template for creating your -own reStructuredText PEPs.

-
- - diff --git a/peps/tests/peps/pep-0012.rst b/peps/tests/peps/pep-0012.rst deleted file mode 100644 index 92a90835e..000000000 --- a/peps/tests/peps/pep-0012.rst +++ /dev/null @@ -1,33 +0,0 @@ -PEP: 12 -Title: Sample reStructuredText PEP Template -Author: David Goodger , - Barry Warsaw -Status: Active -Type: Process -Content-Type: text/x-rst -Created: 05-Aug-2002 -Post-History: 30-Aug-2002 - - -Abstract -======== - -This PEP provides a boilerplate or sample template for creating your -own reStructuredText PEPs. - - -Copyright -========= - -This document has been placed in the public domain. - - - -.. - Local Variables: - mode: indented-text - indent-tabs-mode: nil - sentence-end-double-space: t - fill-column: 70 - coding: utf-8 - End: diff --git a/peps/tests/peps/pep-0525.html b/peps/tests/peps/pep-0525.html deleted file mode 100644 index 55a756e0d..000000000 --- a/peps/tests/peps/pep-0525.html +++ /dev/null @@ -1,595 +0,0 @@ - - --- - - - - - - - - - - - - - - - - - - - - - - - - - -
PEP:525
Title:Asynchronous Generators
Version:$Revision$
Last-Modified:$Date$
Author:Yury Selivanov <yury at magic.io>
Discussions-To:<python-dev at python.org>
Status:Draft
Type:Standards Track
Content-Type:text/x-rst
Created:28-Jul-2016
Python-Version:3.6
Post-History:02-Aug-2016
-
- -
-

Abstract

-

PEP 492 introduced support for native coroutines and async/await -syntax to Python 3.5. It is proposed here to extend Python's -asynchronous capabilities by adding support for -asynchronous generators.

-
-
-

Rationale and Goals

-

Regular generators (introduced in PEP 255) enabled an elegant way of -writing complex data producers and have them behave like an iterator.

-

However, currently there is no equivalent concept for the asynchronous -iteration protocol (async for). This makes writing asynchronous -data producers unnecessarily complex, as one must define a class that -implements __aiter__ and __anext__ to be able to use it in -an async for statement.

-

Essentially, the goals and rationale for PEP 255, applied to the -asynchronous execution case, hold true for this proposal as well.

-

Performance is an additional point for this proposal: in our testing of -the reference implementation, asynchronous generators are 2x faster -than an equivalent implemented as an asynchronous iterator.

-

As an illustration of the code quality improvement, consider the -following class that prints numbers with a given delay once iterated:

-
-class Ticker:
-    """Yield numbers from 0 to `to` every `delay` seconds."""
-
-    def __init__(self, delay, to):
-        self.delay = delay
-        self.i = 0
-        self.to = to
-
-    def __aiter__(self):
-        return self
-
-    async def __anext__(self):
-        i = self.i
-        if i >= self.to:
-            raise StopAsyncIteration
-        self.i += 1
-        if i:
-            await asyncio.sleep(self.delay)
-        return i
-
-

The same can be implemented as a much simpler asynchronous generator:

-
-async def ticker(delay, to):
-    """Yield numbers from 0 to `to` every `delay` seconds."""
-    for i in range(to):
-        yield i
-        await asyncio.sleep(delay)
-
-
-
-

Specification

-

This proposal introduces the concept of asynchronous generators to -Python.

-

This specification presumes knowledge of the implementation of -generators and coroutines in Python (PEP 342, PEP 380 and PEP 492).

-
-

Asynchronous Generators

-

A Python generator is any function containing one or more yield -expressions:

-
-def func():            # a function
-    return
-
-def genfunc():         # a generator function
-    yield
-
-

We propose to use the same approach to define -asynchronous generators:

-
-async def coro():      # a coroutine function
-    await smth()
-
-async def asyncgen():  # an asynchronous generator function
-    await smth()
-    yield 42
-
-

The result of calling an asynchronous generator function is -an asynchronous generator object, which implements the asynchronous -iteration protocol defined in PEP 492.

-

It is a SyntaxError to have a non-empty return statement in an -asynchronous generator.

-
-
-

Support for Asynchronous Iteration Protocol

-

The protocol requires two special methods to be implemented:

-
    -
  1. An __aiter__ method returning an asynchronous iterator.
  2. -
  3. An __anext__ method returning an awaitable object, which uses -StopIteration exception to "yield" values, and -StopAsyncIteration exception to signal the end of the iteration.
  4. -
-

Asynchronous generators define both of these methods. Let's manually -iterate over a simple asynchronous generator:

-
-async def genfunc():
-    yield 1
-    yield 2
-
-gen = genfunc()
-
-assert gen.__aiter__() is gen
-
-assert await gen.__anext__() == 1
-assert await gen.__anext__() == 2
-
-await gen.__anext__()  # This line will raise StopAsyncIteration.
-
-
-
-

Finalization

-

PEP 492 requires an event loop or a scheduler to run coroutines. -Because asynchronous generators are meant to be used from coroutines, -they also require an event loop to run and finalize them.

-

Asynchronous generators can have try..finally blocks, as well as -async with. It is important to provide a guarantee that, even -when partially iterated, and then garbage collected, generators can -be safely finalized. For example:

-
-async def square_series(con, to):
-    async with con.transaction():
-        cursor = con.cursor(
-            'SELECT generate_series(0, $1) AS i', to)
-        async for row in cursor:
-            yield row['i'] ** 2
-
-async for i in square_series(con, 1000):
-    if i == 100:
-        break
-
-

The above code defines an asynchronous generator that uses -async with to iterate over a database cursor in a transaction. -The generator is then iterated over with async for, which interrupts -the iteration at some point.

-

The square_series() generator will then be garbage collected, -and without a mechanism to asynchronously close the generator, Python -interpreter would not be able to do anything.

-

To solve this problem we propose to do the following:

-
    -
  1. Implement an aclose method on asynchronous generators -returning a special awaitable. When awaited it -throws a GeneratorExit into the suspended generator and -iterates over it until either a GeneratorExit or -a StopAsyncIteration occur.

    -

    This is very similar to what the close() method does to regular -Python generators, except that an event loop is required to execute -aclose().

    -
  2. -
  3. Raise a RuntimeError, when an asynchronous generator executes -a yield expression in its finally block (using await -is fine, though):

    -
    -async def gen():
    -    try:
    -        yield
    -    finally:
    -        await asyncio.sleep(1)   # Can use 'await'.
    -
    -        yield                    # Cannot use 'yield',
    -                                 # this line will trigger a
    -                                 # RuntimeError.
    -
    -
  4. -
  5. Add two new methods to the sys module: -set_asyncgen_finalizer() and get_asyncgen_finalizer().

    -
  6. -
-

The idea behind sys.set_asyncgen_finalizer() is to allow event -loops to handle generators finalization, so that the end user -does not need to care about the finalization problem, and it just -works.

-

When an asynchronous generator is iterated for the first time, -it stores a reference to the current finalizer. If there is none, -a RuntimeError is raised. This provides a strong guarantee that -every asynchronous generator object will always have a finalizer -installed by the correct event loop.

-

When an asynchronous generator is about to be garbage collected, -it calls its cached finalizer. The assumption is that the finalizer -will schedule an aclose() call with the loop that was active -when the iteration started.

-

For instance, here is how asyncio is modified to allow safe -finalization of asynchronous generators:

-
-# asyncio/base_events.py
-
-class BaseEventLoop:
-
-    def run_forever(self):
-        ...
-        old_finalizer = sys.get_asyncgen_finalizer()
-        sys.set_asyncgen_finalizer(self._finalize_asyncgen)
-        try:
-            ...
-        finally:
-            sys.set_asyncgen_finalizer(old_finalizer)
-            ...
-
-    def _finalize_asyncgen(self, gen):
-        self.create_task(gen.aclose())
-
-

sys.set_asyncgen_finalizer() is thread-specific, so several event -loops running in parallel threads can use it safely.

-
-
-

Asynchronous Generator Object

-

The object is modeled after the standard Python generator object. -Essentially, the behaviour of asynchronous generators is designed -to replicate the behaviour of synchronous generators, with the only -difference in that the API is asynchronous.

-

The following methods and properties are defined:

-
    -
  1. agen.__aiter__(): Returns agen.

    -
  2. -
  3. agen.__anext__(): Returns an awaitable, that performs one -asynchronous generator iteration when awaited.

    -
  4. -
  5. agen.asend(val): Returns an awaitable, that pushes the -val object in the agen generator. When the agen has -not yet been iterated, val must be None.

    -

    Example:

    -
    -async def gen():
    -    await asyncio.sleep(0.1)
    -    v = yield 42
    -    print(v)
    -    await asyncio.sleep(0.2)
    -
    -g = gen()
    -
    -await g.asend(None)      # Will return 42 after sleeping
    -                         # for 0.1 seconds.
    -
    -await g.asend('hello')   # Will print 'hello' and
    -                         # raise StopAsyncIteration
    -                         # (after sleeping for 0.2 seconds.)
    -
    -
  6. -
  7. agen.athrow(typ, [val, [tb]]): Returns an awaitable, that -throws an exception into the agen generator.

    -

    Example:

    -
    -async def gen():
    -    try:
    -        await asyncio.sleep(0.1)
    -        yield 'hello'
    -    except ZeroDivisionError:
    -        await asyncio.sleep(0.2)
    -        yield 'world'
    -
    -g = gen()
    -v = await g.asend(None)
    -print(v)                # Will print 'hello' after
    -                        # sleeping for 0.1 seconds.
    -
    -v = await g.athrow(ZeroDivisionError)
    -print(v)                # Will print 'world' after
    -                        $ sleeping 0.2 seconds.
    -
    -
  8. -
  9. agen.aclose(): Returns an awaitable, that throws a -GeneratorExit exception into the generator. The awaitable can -either return a yielded value, if agen handled the exception, -or agen will be closed and the exception will propagate back -to the caller.

    -
  10. -
  11. agen.__name__ and agen.__qualname__: readable and writable -name and qualified name attributes.

    -
  12. -
  13. agen.ag_await: The object that agen is currently awaiting -on, or None. This is similar to the currently available -gi_yieldfrom for generators and cr_await for coroutines.

    -
  14. -
  15. agen.ag_frame, agen.ag_running, and agen.ag_code: -defined in the same way as similar attributes of standard generators.

    -
  16. -
-

StopIteration and StopAsyncIteration are not propagated out of -asynchronous generators, and are replaced with a RuntimeError.

-
-
-

Implementation Details

-

Asynchronous generator object (PyAsyncGenObject) shares the -struct layout with PyGenObject. In addition to that, the -reference implementation introduces three new objects:

-
    -
  1. PyAsyncGenASend: the awaitable object that implements -__anext__ and asend() methods.
  2. -
  3. PyAsyncGenAThrow: the awaitable object that implements -athrow() and aclose() methods.
  4. -
  5. _PyAsyncGenWrappedValue: every directly yielded object from an -asynchronous generator is implicitly boxed into this structure. This -is how the generator implementation can separate objects that are -yielded using regular iteration protocol from objects that are -yielded using asynchronous iteration protocol.
  6. -
-

PyAsyncGenASend and PyAsyncGenAThrow are awaitables (they have -__await__ methods returning self) and are coroutine-like objects -(implementing __iter__, __next__, send() and throw() -methods). Essentially, they control how asynchronous generators are -iterated:

-pep-0525-1.png -
-

PyAsyncGenASend and PyAsyncGenAThrow

-

PyAsyncGenASend is a coroutine-like object that drives __anext__ -and asend() methods and implements the asynchronous iteration -protocol.

-

agen.asend(val) and agen.__anext__() return instances of -PyAsyncGenASend (which hold references back to the parent -agen object.)

-

The data flow is defined as follows:

-
    -
  1. When PyAsyncGenASend.send(val) is called for the first time, -val is pushed to the parent agen object (using existing -facilities of PyGenObject.)

    -

    Subsequent iterations over the PyAsyncGenASend objects, push -None to agen.

    -

    When a _PyAsyncGenWrappedValue object is yielded, it -is unboxed, and a StopIteration exception is raised with the -unwrapped value as an argument.

    -
  2. -
  3. When PyAsyncGenASend.throw(*exc) is called for the first time, -*exc is throwed into the parent agen object.

    -

    Subsequent iterations over the PyAsyncGenASend objects, push -None to agen.

    -

    When a _PyAsyncGenWrappedValue object is yielded, it -is unboxed, and a StopIteration exception is raised with the -unwrapped value as an argument.

    -
  4. -
  5. return statements in asynchronous generators raise -StopAsyncIteration exception, which is propagated through -PyAsyncGenASend.send() and PyAsyncGenASend.throw() methods.

    -
  6. -
-

PyAsyncGenAThrow is very similar to PyAsyncGenASend. The only -difference is that PyAsyncGenAThrow.send(), when called first time, -throws an exception into the parent agen object (instead of pushing -a value into it.)

-
-
-
-

New Standard Library Functions and Types

-
    -
  1. types.AsyncGeneratorType -- type of asynchronous generator -object.
  2. -
  3. sys.set_asyncgen_finalizer() and sys.get_asyncgen_finalizer() -methods to set up asynchronous generators finalizers in event loops.
  4. -
  5. inspect.isasyncgen() and inspect.isasyncgenfunction() -introspection functions.
  6. -
-
-
-

Backwards Compatibility

-

The proposal is fully backwards compatible.

-

In Python 3.5 it is a SyntaxError to define an async def -function with a yield expression inside, therefore it's safe to -introduce asynchronous generators in 3.6.

-
-
-
-

Performance

-
-

Regular Generators

-

There is no performance degradation for regular generators. -The following micro benchmark runs at the same speed on CPython with -and without asynchronous generators:

-
-def gen():
-    i = 0
-    while i < 100000000:
-        yield i
-        i += 1
-
-list(gen())
-
-
-
-

Improvements over asynchronous iterators

-

The following micro-benchmark shows that asynchronous generators -are about 2.3x faster than asynchronous iterators implemented in -pure Python:

-
-N = 10 ** 7
-
-async def agen():
-    for i in range(N):
-        yield i
-
-class AIter:
-    def __init__(self):
-        self.i = 0
-
-    def __aiter__(self):
-        return self
-
-    async def __anext__(self):
-        i = self.i
-        if i >= N:
-            raise StopAsyncIteration
-        self.i += 1
-        return i
-
-
-
-
-

Design Considerations

-
-

aiter() and anext() builtins

-

Originally, PEP 492 defined __aiter__ as a method that should -return an awaitable object, resulting in an asynchronous iterator.

-

However, in CPython 3.5.2, __aiter__ was redefined to return -asynchronous iterators directly. To avoid breaking backwards -compatibility, it was decided that Python 3.6 will support both -ways: __aiter__ can still return an awaitable with -a DeprecationWarning being issued.

-

Because of this dual nature of __aiter__ in Python 3.6, we cannot -add a synchronous implementation of aiter() built-in. Therefore, -it is proposed to wait until Python 3.7.

-
-
-

Asynchronous list/dict/set comprehensions

-

Syntax for asynchronous comprehensions is unrelated to the asynchronous -generators machinery, and should be considered in a separate PEP.

-
-
-

Asynchronous yield from

-

While it is theoretically possible to implement yield from support -for asynchronous generators, it would require a serious redesign of the -generators implementation.

-

yield from is also less critical for asynchronous generators, since -there is no need provide a mechanism of implementing another coroutines -protocol on top of coroutines. And to compose asynchronous generators a -simple async for loop can be used:

-
-async def g1():
-    yield 1
-    yield 2
-
-async def g2():
-    async for v in g1():
-        yield v
-
-
-
-

Why the asend() and athrow() methods are necessary

-

They make it possible to implement concepts similar to -contextlib.contextmanager using asynchronous generators. -For instance, with the proposed design, it is possible to implement -the following pattern:

-
-@async_context_manager
-async def ctx():
-    await open()
-    try:
-        yield
-    finally:
-        await close()
-
-async with ctx():
-    await ...
-
-

Another reason is that it is possible to push data and throw exceptions -into asynchronous generators using the object returned from -__anext__ object, but it is hard to do that correctly. Adding -explicit asend() and athrow() will pave a safe way to -accomplish that.

-

In terms of implementation, asend() is a slightly more generic -version of __anext__, and athrow() is very similar to -aclose(). Therefore having these methods defined for asynchronous -generators does not add any extra complexity.

-
-
-
-

Example

-

A working example with the current reference implementation (will -print numbers from 0 to 9 with one second delay):

-
-async def ticker(delay, to):
-    for i in range(to):
-        yield i
-        await asyncio.sleep(delay)
-
-
-async def run():
-    async for i in ticker(1, 10):
-        print(i)
-
-
-import asyncio
-loop = asyncio.get_event_loop()
-try:
-    loop.run_until_complete(run())
-finally:
-    loop.close()
-
-
-
-

Implementation

-

The complete reference implementation is available at [1].

-
- - - diff --git a/peps/tests/peps/pep-3001-1.png b/peps/tests/peps/pep-3001-1.png deleted file mode 100644 index 7f63aea50..000000000 Binary files a/peps/tests/peps/pep-3001-1.png and /dev/null differ diff --git a/peps/tests/peps/pep-3001.html b/peps/tests/peps/pep-3001.html deleted file mode 100644 index bd2da8dbe..000000000 --- a/peps/tests/peps/pep-3001.html +++ /dev/null @@ -1,140 +0,0 @@ - - --- - - - - - - - - - - - - - - - - - - - - - -
PEP:3001
Title:Procedure for reviewing and improving standard library modules
Version:$Revision$
Last-Modified:$Date$
Author:Georg Brandl <georg at python.org>
Status:Withdrawn
Type:Process
Content-Type:text/x-rst
Created:05-Apr-2006
Post-History:
-
- -
-

Abstract

-

This PEP describes a procedure for reviewing and improving standard -library modules, especially those written in Python, making them ready -for Python 3000. There can be different steps of refurbishing, each -of which is described in a section below. Of course, not every step -has to be performed for every module.

-
-
-

Removal of obsolete modules

-

All modules marked as deprecated in 2.x versions should be removed for -Python 3000. The same applies to modules which are seen as obsolete today, -but are too widely used to be deprecated or removed. Python 3000 is the -big occasion to get rid of them. pep-3001-1.png

-

There will have to be a document listing all removed modules, together -with information on possible substitutes or alternatives. This infor- -mation will also have to be provided by the python3warn.py porting -helper script mentioned in PEP XXX.

-
-
-

Renaming modules

-

There are proposals for a "great stdlib renaming" introducing a hierarchic -library namespace or a top-level package from which to import standard -modules. That possibility aside, some modules' names are known to have -been chosen unwisely, a mistake which could never be corrected in the 2.x -series. Examples are names like "StringIO" or "Cookie". For Python 3000, -there will be the possibility to give those modules less confusing and -more conforming names.

-

Of course, each rename will have to be stated in the documentation of -the respective module and perhaps in the global document of Step 1. -Additionally, the python3warn.py script will recognize the old module -names and notify the user accordingly.

-

If the name change is made in time for another release of the Python 2.x -series, it is worth considering to introduce the new name in the 2.x -branch to ease transition.

-
-
-

Code cleanup

-

As most library modules written in Python have not been touched except -for bug fixes, following the policy of never changing a running system, -many of them may contain code that is not up to the newest language -features and could be rewritten in a more concise, modern Python.

-

PyChecker should run cleanly over the library. With a carefully tuned -configuration file, PyLint should also emit as few warnings as possible.

-

As long as these changes don't change the module's interface and behavior, -no documentation updates are necessary.

-
-
-

Enhancement of test and documentation coverage

-

Code coverage by unit tests varies greatly between modules. Each test -suite should be checked for completeness, and the remaining classic tests -should be converted to PyUnit (or whatever new shiny testing framework -comes with Python 3000, perhaps py.test?).

-

It should also be verified that each publicly visible function has a -meaningful docstring which ideally contains several doctests.

-

No documentation changes are necessary for enhancing test coverage.

-
-
-

Unification of module metadata

-

This is a small and probably not very important step. There have been -various attempts at providing author, version and similar metadata in -modules (such as a "__version__" global). Those could be standardized -and used throughout the library.

-

No documentation changes are necessary for this step, too.

-
-
-

Backwards incompatible bug fixes

-

Over the years, many bug reports have been filed which complained about -bugs in standard library modules, but have subsequently been closed as -"Won't fix" since a fix would have introduced a major incompatibility -which was not acceptable in the Python 2.x series. In Python 3000, the -fix can be applied if the interface per se is still acceptable.

-

Each slight behavioral change caused by such fixes must be mentioned in -the documentation, perhaps in a "Changed in Version 3.0" paragraph.

-
-
-

Interface changes

-

The last and most disruptive change is the overhaul of a module's public -interface. If a module's interface is to be changed, a justification -should be made beforehand, or a PEP should be written.

-

The change must be fully documented as "New in Version 3.0", and the -python3warn.py script must know about it.

-
-
-

References

-

None yet.

-
- - diff --git a/peps/tests/test_commands.py b/peps/tests/test_commands.py deleted file mode 100644 index 2579a5f99..000000000 --- a/peps/tests/test_commands.py +++ /dev/null @@ -1,56 +0,0 @@ -import io - -from bs4 import BeautifulSoup - -from django.test import TestCase, override_settings -from django.conf import settings -from django.core import serializers -from django.core.management import call_command - -import responses - -from pages.models import Image - -from . import FAKE_PEP_ARTIFACT - - -PEP_ARTIFACT_URL = 'https://example.net/fake-peps.tar.gz' - - -@override_settings(PEP_ARTIFACT_URL=PEP_ARTIFACT_URL) -class PEPManagementCommandTests(TestCase): - - def setUp(self): - responses.add( - responses.GET, - PEP_ARTIFACT_URL, - headers={'Last-Modified': 'Sun, 24 Feb 2019 18:01:42 GMT'}, - stream=True, - content_type='application/x-tar', - status=200, - body=open(FAKE_PEP_ARTIFACT, 'rb'), - ) - - @responses.activate - def test_generate_pep_pages_real_with_remote_artifact(self): - call_command('generate_pep_pages') - - @override_settings(PEP_ARTIFACT_URL=FAKE_PEP_ARTIFACT) - def test_generate_pep_pages_real_with_local_artifact(self): - call_command('generate_pep_pages') - - @responses.activate - def test_image_generated(self): - call_command('generate_pep_pages') - img = Image.objects.get(page__path='dev/peps/pep-3001/') - soup = BeautifulSoup(img.page.content.raw, 'lxml') - self.assertIn(settings.MEDIA_URL, soup.find('img')['src']) - - @responses.activate - def test_dump_pep_pages(self): - call_command('generate_pep_pages') - stdout = io.StringIO() - call_command('dump_pep_pages', stdout=stdout) - output = stdout.getvalue() - result = list(serializers.deserialize('json', output)) - self.assertGreater(len(result), 0) diff --git a/peps/tests/test_converters.py b/peps/tests/test_converters.py deleted file mode 100644 index 833bf7c0e..000000000 --- a/peps/tests/test_converters.py +++ /dev/null @@ -1,64 +0,0 @@ -from django.test import TestCase, override_settings -from django.core.exceptions import ImproperlyConfigured -from django.test.utils import captured_stdout - -from peps.converters import get_pep0_page, get_pep_page, add_pep_image - -from . import FAKE_PEP_REPO - - -class PEPConverterTests(TestCase): - - def test_source_link(self): - pep = get_pep_page(FAKE_PEP_REPO, '0525') - self.assertEqual(pep.title, 'PEP 525 -- Asynchronous Generators') - self.assertIn( - 'Source: https://github.com/python/peps/blob/master/pep-0525.txt', - pep.content.rendered - ) - - def test_source_link_rst(self): - pep = get_pep_page(FAKE_PEP_REPO, '0012') - self.assertEqual(pep.title, 'PEP 12 -- Sample reStructuredText PEP Template') - self.assertIn( - 'Source: https://github.com/python/peps/blob/master/pep-0012.rst', - pep.content.rendered - ) - - def test_invalid_pep_number(self): - with captured_stdout() as stdout: - get_pep_page(FAKE_PEP_REPO, '9999999') - self.assertRegex( - stdout.getvalue(), - r"PEP Path '(.*)9999999(.*)' does not exist, skipping" - ) - - def test_add_image_not_found(self): - with captured_stdout() as stdout: - add_pep_image(FAKE_PEP_REPO, '0525', '/path/that/does/not/exist') - self.assertRegex( - stdout.getvalue(), - r"Image Path '(.*)/path/that/does/not/exist(.*)' does not exist, skipping" - ) - - def test_html_do_not_prettify(self): - pep = get_pep_page(FAKE_PEP_REPO, '3001') - self.assertEqual( - pep.title, - 'PEP 3001 -- Procedure for reviewing and improving standard library modules' - ) - self.assertIn( - 'Title:' - 'Procedure for reviewing and improving ' - 'standard library modules\n', - pep.content.rendered - ) - - def test_strip_html_and_body_tags(self): - pep = get_pep_page(FAKE_PEP_REPO, '0525') - self.assertNotIn('', pep.content.rendered) - self.assertNotIn('', pep.content.rendered) - self.assertNotIn('', pep.content.rendered) - self.assertNotIn('', pep.content.rendered) diff --git a/pydotorg/settings/base.py b/pydotorg/settings/base.py index 30dc8de4a..2c392b355 100644 --- a/pydotorg/settings/base.py +++ b/pydotorg/settings/base.py @@ -222,7 +222,6 @@ 'minutes', 'nominations', 'pages', - 'peps', 'sponsors', 'successstories', 'users', @@ -285,10 +284,6 @@ ### Registration mailing lists MAILING_LIST_PSF_MEMBERS = "psf-members-announce-request@python.org" -### PEP Repo Location -PEP_REPO_PATH = None -PEP_ARTIFACT_URL = 'https://pythondotorg-assets-staging.s3.amazonaws.com/fake-peps.tar.gz' - ### Fastly ### FASTLY_API_KEY = False # Set to Fastly API key in production to allow pages to # be purged on save diff --git a/templates/components/pep-widget.html b/templates/components/pep-widget.html deleted file mode 100644 index bba29ea2d..000000000 --- a/templates/components/pep-widget.html +++ /dev/null @@ -1,19 +0,0 @@ -{% load peps %} -
- -

- >>> Python Enhancement Proposals (PEPs): The future of Python is discussed here. - -

- - - {# This isn't that awesome, commenting out for now #} - {% comment %} - {% get_newest_pep_pages as peps %} - - {% endcomment %} -
\ No newline at end of file diff --git a/templates/python/documentation.html b/templates/python/documentation.html index 7db3662d2..e301b0010 100644 --- a/templates/python/documentation.html +++ b/templates/python/documentation.html @@ -106,7 +106,4 @@

P - - {% include 'components/pep-widget.html' %} - {% endblock content %} diff --git a/templates/python/index.html b/templates/python/index.html index ac8b191df..753a53407 100644 --- a/templates/python/index.html +++ b/templates/python/index.html @@ -85,8 +85,6 @@ - {% include 'components/pep-widget.html' %} - {% include 'components/psf-widget.html' %} {% endblock content %}