├── .codespell ├── exclude-file.txt └── ignore-words.txt ├── .codespellrc ├── .gitattributes ├── .github ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE │ ├── Add a new PEP.md │ ├── Change an existing PEP.md │ ├── Mark a PEP Accepted or Rejected.md │ ├── Mark a PEP Final.md │ └── Other - infra or meta change.md ├── dependabot.yml └── workflows │ ├── documentation-links.yml │ ├── lint.yml │ ├── render.yml │ └── test.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── .ruff.toml ├── CONTRIBUTING.rst ├── Makefile ├── README.rst ├── build.py ├── check-peps.py ├── docs ├── build.rst └── rendering_system.rst ├── infra ├── .gitignore ├── config.tf └── main.tf ├── pep_sphinx_extensions ├── LICENCE.rst ├── __init__.py ├── generate_rss.py ├── pep_processor │ ├── html │ │ ├── pep_html_builder.py │ │ └── pep_html_translator.py │ ├── parsing │ │ ├── pep_banner_directive.py │ │ ├── pep_parser.py │ │ └── pep_role.py │ └── transforms │ │ ├── pep_contents.py │ │ ├── pep_footer.py │ │ ├── pep_headers.py │ │ ├── pep_references.py │ │ ├── pep_title.py │ │ └── pep_zero.py ├── pep_theme │ ├── static │ │ ├── colour_scheme.js │ │ ├── mq.css │ │ ├── og-image.png │ │ ├── py.png │ │ ├── sticky_banner.js │ │ ├── style.css │ │ └── wrap_tables.js │ ├── templates │ │ ├── page.html │ │ └── partials │ │ │ └── icons.html │ └── theme.conf ├── pep_zero_generator │ ├── constants.py │ ├── errors.py │ ├── parser.py │ ├── pep_index_generator.py │ ├── subindices.py │ └── writer.py └── tests │ ├── __init__.py │ ├── conftest.py │ ├── pep_lint │ ├── __init__.py │ ├── test_date.py │ ├── test_direct_links.py │ ├── test_email.py │ ├── test_headers.py │ ├── test_pep_lint.py │ ├── test_pep_number.py │ └── test_post_url.py │ ├── pep_processor │ └── transform │ │ ├── test_pep_footer.py │ │ ├── test_pep_headers.py │ │ └── test_pep_zero.py │ ├── pep_zero_generator │ ├── test_parser.py │ ├── test_pep_index_generator.py │ └── test_writer.py │ └── peps │ ├── pep-9000.rst │ ├── pep-9001.rst │ └── pep-9002.rst ├── peps ├── conf.py ├── contents.rst ├── pep-0001.rst ├── pep-0001 │ └── process_flow.svg ├── pep-0002.rst ├── pep-0003.rst ├── pep-0004.rst ├── pep-0005.rst ├── pep-0006.rst ├── pep-0007.rst ├── pep-0008.rst ├── pep-0009.rst ├── pep-0010.rst ├── pep-0011.rst ├── pep-0012.rst ├── pep-0012 │ └── pep-NNNN.rst ├── pep-0013.rst ├── pep-0020.rst ├── pep-0042.rst ├── pep-0100.rst ├── pep-0101.rst ├── pep-0102.rst ├── pep-0103.rst ├── pep-0160.rst ├── pep-0200.rst ├── pep-0201.rst ├── pep-0202.rst ├── pep-0203.rst ├── pep-0204.rst ├── pep-0205.rst ├── pep-0206.rst ├── pep-0207.rst ├── pep-0208.rst ├── pep-0209.rst ├── pep-0210.rst ├── pep-0211.rst ├── pep-0212.rst ├── pep-0213.rst ├── pep-0214.rst ├── pep-0215.rst ├── pep-0216.rst ├── pep-0217.rst ├── pep-0218.rst ├── pep-0219.rst ├── pep-0220.rst ├── pep-0221.rst ├── pep-0222.rst ├── pep-0223.rst ├── pep-0224.rst ├── pep-0225.rst ├── pep-0226.rst ├── pep-0227.rst ├── pep-0228.rst ├── pep-0229.rst ├── pep-0230.rst ├── pep-0231.rst ├── pep-0232.rst ├── pep-0233.rst ├── pep-0234.rst ├── pep-0235.rst ├── pep-0236.rst ├── pep-0237.rst ├── pep-0238.rst ├── pep-0239.rst ├── pep-0240.rst ├── pep-0241.rst ├── pep-0242.rst ├── pep-0243.rst ├── pep-0244.rst ├── pep-0245.rst ├── pep-0246.rst ├── pep-0247.rst ├── pep-0248.rst ├── pep-0249.rst ├── pep-0250.rst ├── pep-0251.rst ├── pep-0252.rst ├── pep-0253.rst ├── pep-0254.rst ├── pep-0255.rst ├── pep-0256.rst ├── pep-0257.rst ├── pep-0258.rst ├── pep-0259.rst ├── pep-0260.rst ├── pep-0261.rst ├── pep-0262.rst ├── pep-0263.rst ├── pep-0264.rst ├── pep-0265.rst ├── pep-0266.rst ├── pep-0267.rst ├── pep-0268.rst ├── pep-0269.rst ├── pep-0270.rst ├── pep-0271.rst ├── pep-0272.rst ├── pep-0273.rst ├── pep-0274.rst ├── pep-0275.rst ├── pep-0276.rst ├── pep-0277.rst ├── pep-0278.rst ├── pep-0279.rst ├── pep-0280.rst ├── pep-0281.rst ├── pep-0282.rst ├── pep-0283.rst ├── pep-0284.rst ├── pep-0285.rst ├── pep-0286.rst ├── pep-0287.rst ├── pep-0288.rst ├── pep-0289.rst ├── pep-0290.rst ├── pep-0291.rst ├── pep-0292.rst ├── pep-0293.rst ├── pep-0294.rst ├── pep-0295.rst ├── pep-0296.rst ├── pep-0297.rst ├── pep-0298.rst ├── pep-0299.rst ├── pep-0301.rst ├── pep-0302.rst ├── pep-0303.rst ├── pep-0304.rst ├── pep-0305.rst ├── pep-0306.rst ├── pep-0307.rst ├── pep-0308.rst ├── pep-0309.rst ├── pep-0310.rst ├── pep-0311.rst ├── pep-0312.rst ├── pep-0313.rst ├── pep-0314.rst ├── pep-0315.rst ├── pep-0316.rst ├── pep-0317.rst ├── pep-0318.rst ├── pep-0319.rst ├── pep-0320.rst ├── pep-0321.rst ├── pep-0322.rst ├── pep-0323.rst ├── pep-0324.rst ├── pep-0325.rst ├── pep-0326.rst ├── pep-0327.rst ├── pep-0328.rst ├── pep-0329.rst ├── pep-0330.rst ├── pep-0331.rst ├── pep-0332.rst ├── pep-0333.rst ├── pep-0334.rst ├── pep-0335.rst ├── pep-0336.rst ├── pep-0337.rst ├── pep-0338.rst ├── pep-0339.rst ├── pep-0340.rst ├── pep-0341.rst ├── pep-0342.rst ├── pep-0343.rst ├── pep-0344.rst ├── pep-0345.rst ├── pep-0346.rst ├── pep-0347.rst ├── pep-0348.rst ├── pep-0349.rst ├── pep-0350.rst ├── pep-0351.rst ├── pep-0352.rst ├── pep-0353.rst ├── pep-0354.rst ├── pep-0355.rst ├── pep-0356.rst ├── pep-0357.rst ├── pep-0358.rst ├── pep-0359.rst ├── pep-0360.rst ├── pep-0361.rst ├── pep-0362.rst ├── pep-0363.rst ├── pep-0364.rst ├── pep-0365.rst ├── pep-0366.rst ├── pep-0367.rst ├── pep-0368.rst ├── pep-0369.rst ├── pep-0370.rst ├── pep-0371.rst ├── pep-0372.rst ├── pep-0373.rst ├── pep-0374.rst ├── pep-0375.rst ├── pep-0376.rst ├── pep-0377.rst ├── pep-0378.rst ├── pep-0379.rst ├── pep-0380.rst ├── pep-0381.rst ├── pep-0382.rst ├── pep-0383.rst ├── pep-0384.rst ├── pep-0385.rst ├── pep-0386.rst ├── pep-0387.rst ├── pep-0389.rst ├── pep-0390.rst ├── pep-0391.rst ├── pep-0392.rst ├── pep-0393.rst ├── pep-0394.rst ├── pep-0395.rst ├── pep-0396.rst ├── pep-0397.rst ├── pep-0398.rst ├── pep-0399.rst ├── pep-0400.rst ├── pep-0401.rst ├── pep-0402.rst ├── pep-0403.rst ├── pep-0404.rst ├── pep-0405.rst ├── pep-0406.rst ├── pep-0407.rst ├── pep-0408.rst ├── pep-0409.rst ├── pep-0410.rst ├── pep-0411.rst ├── pep-0412.rst ├── pep-0413.rst ├── pep-0414.rst ├── pep-0415.rst ├── pep-0416.rst ├── pep-0417.rst ├── pep-0418.rst ├── pep-0418 │ ├── bench_time.c │ ├── clock_resolution.py │ └── clockutils.py ├── pep-0419.rst ├── pep-0420.rst ├── pep-0421.rst ├── pep-0422.rst ├── pep-0423.rst ├── pep-0424.rst ├── pep-0425.rst ├── pep-0426.rst ├── pep-0426 │ ├── pepsort.py │ └── pydist-schema.json ├── pep-0427.rst ├── pep-0428.rst ├── pep-0429.rst ├── pep-0430.rst ├── pep-0431.rst ├── pep-0432.rst ├── pep-0433.rst ├── pep-0433 │ ├── bench_cloexec.py │ └── openbsd_bug.py ├── pep-0434.rst ├── pep-0435.rst ├── pep-0436.rst ├── pep-0437.rst ├── pep-0438.rst ├── pep-0439.rst ├── pep-0440.rst ├── pep-0441.rst ├── pep-0442.rst ├── pep-0443.rst ├── pep-0444.rst ├── pep-0445.rst ├── pep-0446.rst ├── pep-0446 │ └── test_cloexec.py ├── pep-0447.rst ├── pep-0448.rst ├── pep-0449.rst ├── pep-0450.rst ├── pep-0451.rst ├── pep-0452.rst ├── pep-0453.rst ├── pep-0454.rst ├── pep-0455.rst ├── pep-0456.rst ├── pep-0457.rst ├── pep-0458-1.png ├── pep-0458.rst ├── pep-0459.rst ├── pep-0460.rst ├── pep-0461.rst ├── pep-0462.rst ├── pep-0463.rst ├── pep-0464.rst ├── pep-0465.rst ├── pep-0465 │ └── scan-ops.py ├── pep-0466.rst ├── pep-0467.rst ├── pep-0468.rst ├── pep-0469.rst ├── pep-0470.rst ├── pep-0471.rst ├── pep-0472.rst ├── pep-0473.rst ├── pep-0474.rst ├── pep-0475.rst ├── pep-0476.rst ├── pep-0477.rst ├── pep-0478.rst ├── pep-0479.rst ├── pep-0480-1.png ├── pep-0480.rst ├── pep-0481.rst ├── pep-0482.rst ├── pep-0483.rst ├── pep-0484.rst ├── pep-0485.rst ├── pep-0486.rst ├── pep-0487.rst ├── pep-0488.rst ├── pep-0489.rst ├── pep-0490.rst ├── pep-0491.rst ├── pep-0492.rst ├── pep-0493.rst ├── pep-0494.rst ├── pep-0495-daylightsavings.png ├── pep-0495-fold.svg ├── pep-0495-gap.svg ├── pep-0495.rst ├── pep-0496.rst ├── pep-0497.rst ├── pep-0498.rst ├── pep-0499.rst ├── pep-0500.rst ├── pep-0501.rst ├── pep-0502.rst ├── pep-0503.rst ├── pep-0504.rst ├── pep-0505.rst ├── pep-0505 │ ├── find-pep505.out │ ├── find-pep505.py │ └── test.py ├── pep-0506.rst ├── pep-0507.rst ├── pep-0508.rst ├── pep-0509.rst ├── pep-0510.rst ├── pep-0511.rst ├── pep-0512.rst ├── pep-0513.rst ├── pep-0514.rst ├── pep-0515.rst ├── pep-0516.rst ├── pep-0517.rst ├── pep-0518.rst ├── pep-0519.rst ├── pep-0520.rst ├── pep-0521.rst ├── pep-0522.rst ├── pep-0523.rst ├── pep-0524.rst ├── pep-0525-1.png ├── pep-0525.rst ├── pep-0526.rst ├── pep-0527.rst ├── pep-0528.rst ├── pep-0529.rst ├── pep-0530.rst ├── pep-0531.rst ├── pep-0532.rst ├── pep-0532 │ └── circuit-breaking-protocol.svg ├── pep-0533.rst ├── pep-0534.rst ├── pep-0535.rst ├── pep-0536.rst ├── pep-0537.rst ├── pep-0538.rst ├── pep-0539.rst ├── pep-0540.rst ├── pep-0541.rst ├── pep-0542.rst ├── pep-0543.rst ├── pep-0544.rst ├── pep-0545.rst ├── pep-0546.rst ├── pep-0547.rst ├── pep-0548.rst ├── pep-0549.rst ├── pep-0550-hamt_vs_dict-v2.png ├── pep-0550-hamt_vs_dict.png ├── pep-0550-lookup_hamt.png ├── pep-0550.rst ├── pep-0551.rst ├── pep-0552.rst ├── pep-0553.rst ├── pep-0554.rst ├── pep-0555.rst ├── pep-0556.rst ├── pep-0557.rst ├── pep-0558.rst ├── pep-0559.rst ├── pep-0560.rst ├── pep-0561.rst ├── pep-0562.rst ├── pep-0563.rst ├── pep-0564.rst ├── pep-0565.rst ├── pep-0566.rst ├── pep-0567.rst ├── pep-0568.rst ├── pep-0569.rst ├── pep-0570.rst ├── pep-0571.rst ├── pep-0572.rst ├── pep-0573.rst ├── pep-0574.rst ├── pep-0575.rst ├── pep-0576.rst ├── pep-0577.rst ├── pep-0578.rst ├── pep-0579.rst ├── pep-0580.rst ├── pep-0581.rst ├── pep-0582.rst ├── pep-0583.rst ├── pep-0584.rst ├── pep-0585.rst ├── pep-0586.rst ├── pep-0587.rst ├── pep-0588.rst ├── pep-0589.rst ├── pep-0590.rst ├── pep-0591.rst ├── pep-0592.rst ├── pep-0593.rst ├── pep-0594.rst ├── pep-0595.rst ├── pep-0596.rst ├── pep-0597.rst ├── pep-0598.rst ├── pep-0599.rst ├── pep-0600.rst ├── pep-0601.rst ├── pep-0602-example-release-calendar.png ├── pep-0602-example-release-calendar.pptx ├── pep-0602-overlapping-support-matrix.png ├── pep-0602-overlapping-support-matrix.pptx ├── pep-0602.rst ├── pep-0603-hamt_vs_dict.png ├── pep-0603-lookup_hamt.png ├── pep-0603.rst ├── pep-0604.rst ├── pep-0605-example-release-calendar.png ├── pep-0605-overlapping-support-matrix.png ├── pep-0605.rst ├── pep-0605 │ ├── example-release-calendar.odp │ └── overlapping-support-matrix.odp ├── pep-0606.rst ├── pep-0607.rst ├── pep-0608.rst ├── pep-0609.rst ├── pep-0610.rst ├── pep-0611.rst ├── pep-0612.rst ├── pep-0613.rst ├── pep-0614.rst ├── pep-0615.rst ├── pep-0616.rst ├── pep-0617.rst ├── pep-0618.rst ├── pep-0619.rst ├── pep-0620.rst ├── pep-0621.rst ├── pep-0622.rst ├── pep-0623.rst ├── pep-0624.rst ├── pep-0625.rst ├── pep-0626.rst ├── pep-0627.rst ├── pep-0628.rst ├── pep-0629.rst ├── pep-0630.rst ├── pep-0631.rst ├── pep-0632.rst ├── pep-0633.rst ├── pep-0634.rst ├── pep-0635.rst ├── pep-0636.rst ├── pep-0637.rst ├── pep-0638.rst ├── pep-0639.rst ├── pep-0639 │ ├── appendix-examples.rst │ ├── appendix-license-survey.rst │ ├── appendix-mapping-classifiers.rst │ ├── appendix-rejected-ideas.rst │ └── appendix-user-scenarios.rst ├── pep-0640.rst ├── pep-0641.rst ├── pep-0642.rst ├── pep-0643.rst ├── pep-0644.rst ├── pep-0645.rst ├── pep-0646.rst ├── pep-0647.rst ├── pep-0648.rst ├── pep-0649.rst ├── pep-0650.rst ├── pep-0651.rst ├── pep-0652.rst ├── pep-0653.rst ├── pep-0654.rst ├── pep-0655.rst ├── pep-0656.rst ├── pep-0657.rst ├── pep-0658.rst ├── pep-0659.rst ├── pep-0660.rst ├── pep-0661.rst ├── pep-0662.rst ├── pep-0662 │ └── pep-0662-editable.json ├── pep-0663.rst ├── pep-0664.rst ├── pep-0665.rst ├── pep-0666.rst ├── pep-0667.rst ├── pep-0668.rst ├── pep-0669.rst ├── pep-0670.rst ├── pep-0671.rst ├── pep-0672.rst ├── pep-0673.rst ├── pep-0674.rst ├── pep-0675.rst ├── pep-0676.rst ├── pep-0677.rst ├── pep-0678.rst ├── pep-0679.rst ├── pep-0680.rst ├── pep-0681.rst ├── pep-0682.rst ├── pep-0683.rst ├── pep-0684.rst ├── pep-0685.rst ├── pep-0686.rst ├── pep-0687.rst ├── pep-0688.rst ├── pep-0689.rst ├── pep-0690.rst ├── pep-0691.rst ├── pep-0692.rst ├── pep-0693.rst ├── pep-0694.rst ├── pep-0695.rst ├── pep-0696.rst ├── pep-0697.rst ├── pep-0698.rst ├── pep-0699.rst ├── pep-0700.rst ├── pep-0701.rst ├── pep-0702.rst ├── pep-0703.rst ├── pep-0704.rst ├── pep-0705.rst ├── pep-0706.rst ├── pep-0707.rst ├── pep-0708.rst ├── pep-0709.rst ├── pep-0710.rst ├── pep-0711.rst ├── pep-0712.rst ├── pep-0713.rst ├── pep-0714.rst ├── pep-0715.rst ├── pep-0718.rst ├── pep-0719.rst ├── pep-0720.rst ├── pep-0721.rst ├── pep-0722.rst ├── pep-0723.rst ├── pep-0724.rst ├── pep-0725.rst ├── pep-0726.rst ├── pep-0727.rst ├── pep-0728.rst ├── pep-0729.rst ├── pep-0730.rst ├── pep-0731.rst ├── pep-0732-concentric.drawio.svg ├── pep-0732.rst ├── pep-0733.rst ├── pep-0734.rst ├── pep-0735.rst ├── pep-0736.rst ├── pep-0737.rst ├── pep-0738.rst ├── pep-0739.rst ├── pep-0740.rst ├── pep-0741.rst ├── pep-0742.rst ├── pep-0743.rst ├── pep-0744.rst ├── pep-0745.rst ├── pep-0754.rst ├── pep-0801.rst ├── pep-3000.rst ├── pep-3001.rst ├── pep-3002.rst ├── pep-3003.rst ├── pep-3099.rst ├── pep-3100.rst ├── pep-3101.rst ├── pep-3102.rst ├── pep-3103.rst ├── pep-3104.rst ├── pep-3105.rst ├── pep-3106.rst ├── pep-3107.rst ├── pep-3108.rst ├── pep-3109.rst ├── pep-3110.rst ├── pep-3111.rst ├── pep-3112.rst ├── pep-3113.rst ├── pep-3114.rst ├── pep-3115.rst ├── pep-3116.rst ├── pep-3117.rst ├── pep-3118.rst ├── pep-3119.rst ├── pep-3120.rst ├── pep-3121.rst ├── pep-3122.rst ├── pep-3123.rst ├── pep-3124.rst ├── pep-3125.rst ├── pep-3126.rst ├── pep-3127.rst ├── pep-3128.rst ├── pep-3129.rst ├── pep-3130.rst ├── pep-3131.rst ├── pep-3132.rst ├── pep-3133.rst ├── pep-3134.rst ├── pep-3135.rst ├── pep-3136.rst ├── pep-3137.rst ├── pep-3138.rst ├── pep-3139.rst ├── pep-3140.rst ├── pep-3141.rst ├── pep-3142.rst ├── pep-3143.rst ├── pep-3144.rst ├── pep-3145.rst ├── pep-3146.rst ├── pep-3147-1.dia ├── pep-3147-1.png ├── pep-3147.rst ├── pep-3148.rst ├── pep-3149.rst ├── pep-3150.rst ├── pep-3151.rst ├── pep-3152.rst ├── pep-3153.rst ├── pep-3154.rst ├── pep-3155.rst ├── pep-3156.rst ├── pep-3333.rst ├── pep-8000.rst ├── pep-8001.rst ├── pep-8002.rst ├── pep-8010.rst ├── pep-8011.rst ├── pep-8012.rst ├── pep-8013.rst ├── pep-8014.rst ├── pep-8015.rst ├── pep-8016.rst ├── pep-8100.rst ├── pep-8101.rst ├── pep-8102.rst ├── pep-8103.rst ├── pep-8104.rst └── pep-8105.rst ├── pytest.ini ├── requirements.txt └── tox.ini /.codespell/exclude-file.txt: -------------------------------------------------------------------------------- 1 | of scoped seem allright. I still think there is not enough need 2 | 3 | da de dum, hmm, hmm, dum de dum. 4 | 5 | output=`dmesg | grep hda` 6 | p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) 7 | 8 | Error-de_DE=Wenn ist das Nunstück git und Slotermeyer? 9 | Ja! Beiherhund das Oder die Virtualenvironment gersput! 10 | 11 | `__ 12 | 13 | class ClassE[T: [str, int]]: ... # Type checker error: illegal expression form 14 | class ClassE[T: t1]: ... # Type checker error: literal tuple expression required 15 | 16 | explicitly declared using ``in``, ``out`` and ``inout`` keywords. 17 | | | | | | | | inout | 18 | -------------------------------------------------------------------------------- /.codespell/ignore-words.txt: -------------------------------------------------------------------------------- 1 | adaptee 2 | ancilliary 3 | ans 4 | anull 5 | arithmetics 6 | asend 7 | ba 8 | ccompiler 9 | clos 10 | complies 11 | crate 12 | dedented 13 | dota 14 | extraversion 15 | falsy 16 | fo 17 | groth 18 | iif 19 | implementor 20 | implementors 21 | nd 22 | ned 23 | re-usable 24 | re-use 25 | recuse 26 | reenable 27 | referencable 28 | therefor 29 | warmup 30 | -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | skip = ./.git 3 | ignore-words = .codespell/ignore-words.txt 4 | exclude-file = .codespell/exclude-file.txt 5 | uri-ignore-words-list = daa,ist,searchin,theses 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ensure files are always checked in with consistent line endings 2 | * text eol=lf 3 | *.png binary 4 | *.pptx binary 5 | *.odp binary 6 | 7 | # Instruct linguist not to ignore the PEPs 8 | # https://github.com/github-linguist/linguist/blob/master/docs/overrides.md 9 | peps/*.rst text linguist-detectable 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/Add a new PEP.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ## Basic requirements (all PEP Types) 11 | 12 | * [ ] Read and followed [PEP 1](https://peps.python.org/1) & [PEP 12](https://peps.python.org/12) 13 | * [ ] File created from the [latest PEP template](https://github.com/python/peps/blob/main/peps/pep-0012/pep-NNNN.rst?plain=1) 14 | * [ ] PEP has next available number, & set in filename (``pep-NNNN.rst``), PR title (``PEP 123: ``) and ``PEP`` header 15 | * [ ] Title clearly, accurately and concisely describes the content in 79 characters or less 16 | * [ ] Core dev/PEP editor listed as ``Author`` or ``Sponsor``, and formally confirmed their approval 17 | * [ ] ``Author``, ``Status`` (``Draft``), ``Type`` and ``Created`` headers filled out correctly 18 | * [ ] ``PEP-Delegate``, ``Topic``, ``Requires`` and ``Replaces`` headers completed if appropriate 19 | * [ ] Required sections included 20 | * [ ] Abstract (first section) 21 | * [ ] Copyright (last section; exact wording from template required) 22 | * [ ] Code is well-formatted (PEP 7/PEP 8) and is in [code blocks, with the right lexer names](https://peps.python.org/pep-0012/#literal-blocks) if non-Python 23 | * [ ] PEP builds with no warnings, pre-commit checks pass and content displays as intended in the rendered HTML 24 | * [ ] Authors/sponsor added to ``.github/CODEOWNERS`` for the PEP 25 | 26 | 27 | ## Standards Track requirements 28 | 29 | * [ ] PEP topic [discussed in a suitable venue](https://peps.python.org/pep-0001/#start-with-an-idea-for-python) with general agreement that a PEP is appropriate 30 | * [ ] [Suggested sections](https://peps.python.org/pep-0012/#suggested-sections) included (unless not applicable) 31 | * [ ] Motivation 32 | * [ ] Rationale 33 | * [ ] Specification 34 | * [ ] Backwards Compatibility 35 | * [ ] Security Implications 36 | * [ ] How to Teach This 37 | * [ ] Reference Implementation 38 | * [ ] Rejected Ideas 39 | * [ ] Open Issues 40 | * [ ] ``Python-Version`` set to valid (pre-beta) future Python version, if relevant 41 | * [ ] Any project stated in the PEP as supporting/endorsing/benefiting from the PEP formally confirmed such 42 | * [ ] Right before or after initial merging, [PEP discussion thread](https://peps.python.org/pep-0001/#discussing-a-pep) created and linked to in ``Discussions-To`` and ``Post-History`` 43 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/Change an existing PEP.md: -------------------------------------------------------------------------------- 1 | <!-- 2 | **Please** read our Contributing Guidelines (CONTRIBUTING.rst) 3 | to make sure this repo is the right place for your proposed change. Thanks! 4 | --> 5 | 6 | * Change is either: 7 | * [ ] To a Draft PEP 8 | * [ ] To an Accepted or Final PEP, with Steering Council approval 9 | * [ ] To fix an editorial issue (markup, typo, link, header, etc) 10 | * [ ] PR title prefixed with PEP number (e.g. ``PEP 123: Summary of changes``) 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/Mark a PEP Accepted or Rejected.md: -------------------------------------------------------------------------------- 1 | <!-- 2 | You can help complete the following checklist yourself if you like 3 | by ticking any boxes you're sure about, like this: [x] 4 | 5 | If you're unsure about anything, just leave it blank and we'll take a look. 6 | --> 7 | 8 | * [ ] SC/PEP Delegate has formally accepted/rejected the PEP and posted to the ``Discussions-To`` thread 9 | * [ ] Pull request title in appropriate format (``PEP 123: Mark as Accepted``) 10 | * [ ] ``Status`` changed to ``Accepted``/``Rejected`` 11 | * [ ] ``Resolution`` link points directly to SC/PEP Delegate official acceptance/rejected post 12 | * [ ] Acceptance/rejection notice added, if the SC/PEP delegate had major conditions or comments 13 | * [ ] ``Discussions-To``, ``Post-History`` and ``Python-Version`` up to date 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/Mark a PEP Final.md: -------------------------------------------------------------------------------- 1 | <!-- 2 | You can help complete the following checklist yourself if you like 3 | by ticking any boxes you're sure about, like this: [x] 4 | If you're unsure about something, just leave it blank and we'll take a look. 5 | --> 6 | 7 | * [ ] Final implementation has been merged (including tests and docs) 8 | * [ ] PEP matches the final implementation 9 | * [ ] Any substantial changes since the accepted version approved by the SC/PEP delegate 10 | * [ ] Pull request title in appropriate format (``PEP 123: Mark Final``) 11 | * [ ] ``Status`` changed to ``Final`` (and ``Python-Version`` is correct) 12 | * [ ] Canonical docs/spec linked with a ``canonical-doc`` directive 13 | (or ``canonical-pypa-spec`` for packaging PEPs, 14 | or ``canonical-typing-spec`` for typing PEPs) 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/Other - infra or meta change.md: -------------------------------------------------------------------------------- 1 | <!-- 2 | This template is for an infra or meta change not belonging to another category. 3 | **Please** read our Contributing Guidelines (CONTRIBUTING.rst) 4 | to make sure this repo is the right place for your proposed change. Thanks! 5 | --> 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | groups: 8 | actions: 9 | patterns: 10 | - "*" 11 | -------------------------------------------------------------------------------- /.github/workflows/documentation-links.yml: -------------------------------------------------------------------------------- 1 | name: Read the Docs PR preview 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | documentation-links: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: readthedocs/actions/preview@v1 21 | with: 22 | project-slug: "pep-previews" 23 | single-version: "true" 24 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint PEPs 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | permissions: 6 | contents: read 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 10 | cancel-in-progress: true 11 | 12 | env: 13 | FORCE_COLOR: 1 14 | RUFF_FORMAT: github 15 | 16 | jobs: 17 | pre-commit: 18 | name: Run pre-commit 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | - name: Set up Python 3 24 | uses: actions/setup-python@v5 25 | with: 26 | python-version: "3.x" 27 | cache: pip 28 | 29 | - name: Run pre-commit hooks 30 | uses: pre-commit/action@v3.0.1 31 | 32 | - name: Check spelling 33 | uses: pre-commit/action@v3.0.1 34 | with: 35 | extra_args: --all-files --hook-stage manual codespell || true 36 | 37 | check-peps: 38 | name: Run check-peps 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v4 43 | - name: Set up Python 3 44 | uses: actions/setup-python@v5 45 | with: 46 | python-version: "3" 47 | 48 | - name: Run check-peps 49 | run: python check-peps.py --detailed 50 | -------------------------------------------------------------------------------- /.github/workflows/render.yml: -------------------------------------------------------------------------------- 1 | name: Render PEPs 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | permissions: 6 | contents: read 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 10 | cancel-in-progress: true 11 | 12 | env: 13 | FORCE_COLOR: 1 14 | 15 | jobs: 16 | render-peps: 17 | name: Render PEPs 18 | runs-on: ubuntu-latest 19 | permissions: 20 | contents: write 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | python-version: 25 | - "3.x" 26 | - "3.13-dev" 27 | 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | with: 32 | fetch-depth: 0 # fetch all history so that last modified date-times are accurate 33 | 34 | - name: Set up Python ${{ matrix.python-version }} 35 | uses: actions/setup-python@v5 36 | with: 37 | python-version: ${{ matrix.python-version }} 38 | cache: pip 39 | 40 | - name: Update pip 41 | run: | 42 | python -m pip install --upgrade pip 43 | 44 | - name: Render PEPs 45 | run: make dirhtml JOBS=$(nproc) 46 | 47 | # remove the .doctrees folder when building for deployment as it takes two thirds of disk space 48 | - name: Clean up files 49 | run: rm -r build/.doctrees/ 50 | 51 | - name: Deploy to GitHub pages 52 | # This allows CI to build branches for testing 53 | if: (github.ref == 'refs/heads/main') && (matrix.python-version == '3.x') 54 | uses: JamesIves/github-pages-deploy-action@v4 55 | with: 56 | folder: build # Synchronise with Makefile -> BUILDDIR 57 | single-commit: true # Delete existing files 58 | 59 | - name: Purge CDN cache 60 | if: github.ref == 'refs/heads/main' 61 | run: | 62 | curl -H "Accept: application/json" -H "Fastly-Key: $FASTLY_TOKEN" -X POST "https://api.fastly.com/service/$FASTLY_SERVICE_ID/purge_all" 63 | env: 64 | FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }} 65 | FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }} 66 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test Sphinx Extensions 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/workflows/test.yml" 7 | - "pep_sphinx_extensions/**" 8 | - "tox.ini" 9 | pull_request: 10 | paths: 11 | - ".github/workflows/test.yml" 12 | - "pep_sphinx_extensions/**" 13 | - "tox.ini" 14 | workflow_dispatch: 15 | 16 | permissions: 17 | contents: read 18 | 19 | concurrency: 20 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 21 | cancel-in-progress: true 22 | 23 | env: 24 | FORCE_COLOR: 1 25 | 26 | jobs: 27 | test: 28 | runs-on: ${{ matrix.os }} 29 | strategy: 30 | fail-fast: false 31 | matrix: 32 | python-version: 33 | - "3.9" 34 | - "3.10" 35 | - "3.11" 36 | - "3.12" 37 | - "3.13" 38 | os: 39 | - "windows-latest" 40 | - "macos-latest" 41 | - "ubuntu-latest" 42 | # Python 3.9 is on macos-13 but not macos-latest (macos-14-arm64) 43 | # https://github.com/actions/setup-python/issues/696#issuecomment-1637587760 44 | exclude: 45 | - { python-version: "3.9", os: "macos-latest" } 46 | include: 47 | - { python-version: "3.9", os: "macos-13" } 48 | 49 | 50 | steps: 51 | - uses: actions/checkout@v4 52 | - name: Set up Python ${{ matrix.python-version }} 53 | uses: actions/setup-python@v5 54 | with: 55 | python-version: ${{ matrix.python-version }} 56 | cache: pip 57 | allow-prereleases: true 58 | 59 | - name: Install dependencies 60 | run: | 61 | python -m pip install -U pip 62 | python -m pip install -U wheel 63 | python -m pip install -U tox 64 | 65 | - name: Run tests 66 | run: | 67 | tox -e py -- -v --cov-report term 68 | 69 | - name: Upload coverage 70 | uses: codecov/codecov-action@v4 71 | with: 72 | flags: ${{ matrix.os }} 73 | name: ${{ matrix.os }} Python ${{ matrix.python-version }} 74 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # PEPs 2 | pep-0000.rst 3 | peps.rss 4 | topic 5 | /build 6 | 7 | # Bytecode 8 | __pycache__ 9 | *.py[co] 10 | 11 | # Editors 12 | *~ 13 | .idea 14 | .vscode 15 | *.swp 16 | 17 | # Tests 18 | coverage.xml 19 | .coverage 20 | .tox 21 | 22 | # Virtual environments 23 | *env 24 | /venv 25 | 26 | # Builds 27 | /sphinx-warnings.txt -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | # Project page: https://readthedocs.org/projects/pep-previews/ 4 | 5 | version: 2 6 | 7 | build: 8 | os: ubuntu-22.04 9 | tools: 10 | python: "3" 11 | 12 | commands: 13 | - make dirhtml JOBS=$(nproc) BUILDDIR=_readthedocs/html 14 | 15 | sphinx: 16 | builder: dirhtml 17 | 18 | search: 19 | ignore: ['*'] 20 | -------------------------------------------------------------------------------- /.ruff.toml: -------------------------------------------------------------------------------- 1 | output-format = "full" 2 | target-version = "py39" 3 | 4 | [lint] 5 | ignore = [ 6 | "E501", # Line too long 7 | ] 8 | 9 | select = [ 10 | "E", # pycodestyle errors 11 | "F", # pyflakes 12 | "I", # isort 13 | "PT", # flake8-pytest-style 14 | "W", # pycodestyle warnings 15 | ] 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Builds PEP files to HTML using sphinx 2 | 3 | # You can set these variables from the command line. 4 | PYTHON = python3 5 | VENVDIR = .venv 6 | # synchronise with render.yml -> deploy step 7 | BUILDDIR = build 8 | SPHINXBUILD = PATH=$(VENVDIR)/bin:$$PATH sphinx-build 9 | BUILDER = html 10 | JOBS = auto 11 | SOURCES = 12 | SPHINXERRORHANDLING = -W --keep-going -w sphinx-warnings.txt 13 | 14 | ALLSPHINXOPTS = -b $(BUILDER) \ 15 | -j $(JOBS) \ 16 | $(SPHINXOPTS) $(SPHINXERRORHANDLING) \ 17 | peps $(BUILDDIR) $(SOURCES) 18 | 19 | ## html to render PEPs to "pep-NNNN.html" files 20 | .PHONY: html 21 | html: venv 22 | $(SPHINXBUILD) $(ALLSPHINXOPTS) 23 | 24 | ## htmlview to open the index page built by the html target in your browser 25 | .PHONY: htmlview 26 | htmlview: html 27 | $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/index.html'))" 28 | 29 | ## htmllive to rebuild and reload HTML files in your browser 30 | .PHONY: htmllive 31 | htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild 32 | htmllive: SPHINXERRORHANDLING = --re-ignore="/\.idea/|/venv/|/pep-0000.rst|/topic/" --open-browser --delay 0 33 | htmllive: html 34 | 35 | ## dirhtml to render PEPs to "index.html" files within "pep-NNNN" directories 36 | .PHONY: dirhtml 37 | dirhtml: BUILDER = dirhtml 38 | dirhtml: html 39 | 40 | ## linkcheck to check validity of links within PEP sources 41 | .PHONY: linkcheck 42 | linkcheck: BUILDER = linkcheck 43 | linkcheck: html 44 | 45 | ## check-links (deprecated: use 'make linkcheck' alias instead) 46 | .PHONY: pages 47 | check-links: linkcheck 48 | @echo "\033[0;33mWarning:\033[0;31m 'make check-links' \033[0;33mis deprecated, use\033[0;32m 'make linkcheck' \033[0;33malias instead\033[0m" 49 | 50 | ## clean to remove the venv and build files 51 | .PHONY: clean 52 | clean: clean-venv 53 | -rm -rf build topic 54 | 55 | ## clean-venv to remove the venv 56 | .PHONY: clean-venv 57 | clean-venv: 58 | rm -rf $(VENVDIR) 59 | 60 | ## venv to create a venv with necessary tools 61 | .PHONY: venv 62 | venv: 63 | @if [ -d $(VENVDIR) ] ; then \ 64 | echo "venv already exists."; \ 65 | echo "To recreate it, remove it first with \`make clean-venv'."; \ 66 | else \ 67 | echo "Creating venv in $(VENVDIR)"; \ 68 | $(PYTHON) -m venv $(VENVDIR); \ 69 | $(VENVDIR)/bin/python3 -m pip install -U pip wheel; \ 70 | $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ 71 | echo "The venv has been created in the $(VENVDIR) directory"; \ 72 | fi 73 | 74 | ## lint to lint all the files 75 | .PHONY: lint 76 | lint: venv 77 | $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit 78 | $(VENVDIR)/bin/python3 -m pre_commit run --all-files 79 | 80 | ## test to test the Sphinx extensions for PEPs 81 | .PHONY: test 82 | test: venv 83 | $(VENVDIR)/bin/python3 -bb -X dev -W error -m pytest 84 | 85 | ## spellcheck to check spelling 86 | .PHONY: spellcheck 87 | spellcheck: venv 88 | $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit 89 | $(VENVDIR)/bin/python3 -m pre_commit run --all-files --hook-stage manual codespell 90 | 91 | .PHONY: help 92 | help : Makefile 93 | @echo "Please use \`make <target>' where <target> is one of" 94 | @sed -n 's/^##//p' $< 95 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Python Enhancement Proposals 2 | ============================ 3 | 4 | .. image:: https://github.com/python/peps/actions/workflows/render.yml/badge.svg 5 | :target: https://github.com/python/peps/actions 6 | 7 | The PEPs in this repo are published automatically on the web at 8 | https://peps.python.org/. To learn more about the purpose of PEPs and how to go 9 | about writing one, please start reading at :pep:`1`. Note that the PEP Index 10 | (:pep:`0`) is automatically generated based on the metadata headers in other PEPs. 11 | 12 | 13 | Canonical links 14 | =============== 15 | 16 | The canonical form of PEP links are zero-padded, such as 17 | ``https://peps.python.org/pep-0008/``. 18 | 19 | Shortcut redirects are also available. 20 | For example, ``https://peps.python.org/8`` redirects to the canonical link. 21 | 22 | 23 | Contributing to PEPs 24 | ==================== 25 | 26 | See the `Contributing Guidelines <./CONTRIBUTING.rst>`_. 27 | 28 | 29 | Checking PEP formatting and rendering 30 | ===================================== 31 | 32 | Please don't commit changes with reStructuredText syntax errors that cause PEP 33 | generation to fail, or result in major rendering defects relative to what you 34 | intend. 35 | 36 | 37 | Browse the "Read the Docs" preview 38 | ---------------------------------- 39 | 40 | For every PR, we automatically create a preview of the rendered PEPs using 41 | `Read the Docs <https://about.readthedocs.com>`_. 42 | You can find it in the merge box at the bottom of the PR page: 43 | 44 | 1. Click "Show all checks" to expand the checks section 45 | 2. Find the line for ``docs/readthedocs.org:pep-previews`` 46 | 3. Click on "Details" to the right 47 | 48 | 49 | Render PEPs locally 50 | ------------------- 51 | 52 | See the `build documentation <./docs/build.rst>`__ for full 53 | instructions on how to render PEPs locally. 54 | In summary, run the following in a fresh, activated virtual environment: 55 | 56 | .. code-block:: bash 57 | 58 | # Install requirements 59 | python -m pip install -U -r requirements.txt 60 | 61 | # Build the PEPs 62 | make html 63 | 64 | # Or, if you don't have 'make': 65 | python build.py 66 | 67 | The output HTML is found under the ``build`` directory. 68 | 69 | 70 | Check and lint PEPs 71 | ------------------- 72 | 73 | You can check for and fix common linting and spelling issues, 74 | either on-demand or automatically as you commit, with our pre-commit suite. 75 | See the `Contributing Guide <./CONTRIBUTING.rst>`_ for details. 76 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # This file is placed in the public domain or under the 3 | # CC0-1.0-Universal license, whichever is more permissive. 4 | 5 | """Build script for Sphinx documentation""" 6 | 7 | import argparse 8 | import os 9 | from pathlib import Path 10 | 11 | from sphinx.application import Sphinx 12 | 13 | 14 | def create_parser(): 15 | parser = argparse.ArgumentParser(description="Build PEP documents") 16 | # alternative builders: 17 | builders = parser.add_mutually_exclusive_group() 18 | builders.add_argument("-l", "--check-links", action="store_const", 19 | dest="builder", const="linkcheck", 20 | help='Check validity of links within PEP sources. ' 21 | 'Cannot be used with "-f" or "-d".') 22 | builders.add_argument("-f", "--build-files", action="store_const", 23 | dest="builder", const="html", 24 | help='Render PEPs to "pep-NNNN.html" files (default). ' 25 | 'Cannot be used with "-d" or "-l".') 26 | builders.add_argument("-d", "--build-dirs", action="store_const", 27 | dest="builder", const="dirhtml", 28 | help='Render PEPs to "index.html" files within "pep-NNNN" directories. ' 29 | 'Cannot be used with "-f" or "-l".') 30 | 31 | parser.add_argument( 32 | "-o", 33 | "--output-dir", 34 | default="build", 35 | help="Output directory, relative to root. Default 'build'.", 36 | ) 37 | 38 | return parser.parse_args() 39 | 40 | 41 | def create_index_file(html_root: Path, builder: str) -> None: 42 | """Copies PEP 0 to the root index.html so that /peps/ works.""" 43 | pep_zero_file = "pep-0000.html" if builder == "html" else "pep-0000/index.html" 44 | try: 45 | pep_zero_text = html_root.joinpath(pep_zero_file).read_text(encoding="utf-8") 46 | except FileNotFoundError: 47 | return None 48 | if builder == "dirhtml": 49 | pep_zero_text = pep_zero_text.replace('="../', '="') # remove relative directory links 50 | html_root.joinpath("index.html").write_text(pep_zero_text, encoding="utf-8") 51 | 52 | 53 | if __name__ == "__main__": 54 | args = create_parser() 55 | 56 | root_directory = Path(__file__).resolve().parent 57 | source_directory = root_directory / "peps" 58 | build_directory = root_directory / args.output_dir 59 | 60 | # builder configuration 61 | sphinx_builder = args.builder or "html" 62 | 63 | app = Sphinx( 64 | source_directory, 65 | confdir=source_directory, 66 | outdir=build_directory / sphinx_builder, 67 | doctreedir=build_directory / "doctrees", 68 | buildername=sphinx_builder, 69 | warningiserror=True, 70 | parallel=os.cpu_count() or 1, 71 | tags=["internal_builder"], 72 | keep_going=True, 73 | ) 74 | app.build() 75 | 76 | create_index_file(build_directory, sphinx_builder) 77 | -------------------------------------------------------------------------------- /docs/build.rst: -------------------------------------------------------------------------------- 1 | :author: Adam Turner 2 | 3 | 4 | Building PEPs Locally 5 | ===================== 6 | 7 | Whilst editing a PEP, it is useful to review the rendered output locally. 8 | This can also be used to check that the PEP is valid reStructuredText before 9 | submission to the PEP editors. 10 | 11 | The rest of this document assumes you are working from a local clone of the 12 | `PEPs repository <https://github.com/python/peps>`__, 13 | with **Python 3.9 or later** installed. 14 | 15 | 16 | Render PEPs locally 17 | ------------------- 18 | 19 | 1. Create a virtual environment and install requirements: 20 | 21 | .. code-block:: shell 22 | 23 | make venv 24 | 25 | If you don't have access to ``make``, run: 26 | 27 | .. code-block:: ps1con 28 | 29 | PS> python -m venv .venv 30 | PS> .\.venv\Scripts\activate 31 | (venv) PS> python -m pip install --upgrade pip 32 | (venv) PS> python -m pip install -r requirements.txt 33 | 34 | 2. **(Optional)** Delete prior build files. 35 | Generally only needed when making changes to the rendering system itself. 36 | 37 | .. code-block:: shell 38 | 39 | rm -rf build 40 | 41 | 3. Run the build script: 42 | 43 | .. code-block:: shell 44 | 45 | make html 46 | 47 | If you don't have access to ``make``, run: 48 | 49 | .. code-block:: ps1con 50 | 51 | (venv) PS> python build.py 52 | 53 | 4. Navigate to the ``build`` directory of your PEPs repo to find the HTML pages. 54 | PEP 0 provides a formatted index, and may be a useful reference. 55 | 56 | 57 | ``build.py`` tools 58 | ------------------ 59 | 60 | Several additional tools can be run through ``build.py``, or the Makefile. 61 | 62 | Note that before using ``build.py`` you must activate the virtual environment 63 | created earlier: 64 | 65 | .. code-block:: shell 66 | 67 | source .venv/bin/activate 68 | 69 | Or on Windows: 70 | 71 | .. code-block:: ps1con 72 | 73 | PS> .\.venv\Scripts\activate 74 | 75 | 76 | Check links 77 | ''''''''''' 78 | 79 | Check the validity of links within PEP sources (runs the `Sphinx linkchecker 80 | <https://www.sphinx-doc.org/en/master/usage/builders/index.html#sphinx.builders.linkcheck.CheckExternalLinksBuilder>`__). 81 | 82 | .. code-block:: shell 83 | 84 | python build.py --check-links 85 | make linkcheck 86 | 87 | 88 | ``build.py`` usage 89 | ------------------ 90 | 91 | For details on the command-line options to the ``build.py`` script, run: 92 | 93 | .. code-block:: shell 94 | 95 | python build.py --help 96 | -------------------------------------------------------------------------------- /infra/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform* 2 | terraform.tfstate* 3 | -------------------------------------------------------------------------------- /infra/config.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | fastly = { 4 | source = "fastly/fastly" 5 | version = "1.1.2" 6 | } 7 | } 8 | required_version = ">= 1.1.8" 9 | cloud { 10 | organization = "psf" 11 | workspaces { 12 | name = "peps" 13 | } 14 | } 15 | } 16 | variable "fastly_token" { 17 | type = string 18 | sensitive = true 19 | } 20 | provider "fastly" { 21 | api_key = var.fastly_token 22 | } 23 | -------------------------------------------------------------------------------- /infra/main.tf: -------------------------------------------------------------------------------- 1 | resource "fastly_service_vcl" "peps" { 2 | name = "peps.python.org" 3 | activate = true 4 | domain { name = "peps.python.org" } 5 | 6 | backend { 7 | name = "GitHub Pages" 8 | address = "python.github.io" 9 | port = 443 10 | override_host = "peps.python.org" 11 | 12 | use_ssl = true 13 | ssl_check_cert = true 14 | ssl_cert_hostname = "python.github.io" 15 | ssl_sni_hostname = "python.github.io" 16 | } 17 | 18 | header { 19 | name = "HSTS" 20 | type = "response" 21 | action = "set" 22 | destination = "http.Strict-Transport-Security" 23 | ignore_if_set = false 24 | source = "\"max-age=31536000; includeSubDomains; preload\"" 25 | } 26 | 27 | request_setting { 28 | name = "Force TLS" 29 | force_ssl = true 30 | } 31 | 32 | snippet { 33 | name = "serve-rss" 34 | type = "recv" 35 | content = <<-EOT 36 | if (req.url == "/peps.rss/") { 37 | set req.url = "/peps.rss"; 38 | } 39 | EOT 40 | } 41 | 42 | snippet { 43 | name = "topics" 44 | type = "recv" 45 | content = <<-EOT 46 | if (req.url ~ "^/topics($|/)") { 47 | set req.http.Location = regsub(req.http.Location, "^/topics/?", "/topic/"); 48 | error 618; 49 | } 50 | EOT 51 | } 52 | 53 | snippet { 54 | name = "redirect" 55 | type = "error" 56 | content = <<-EOT 57 | if (obj.status == 618) { 58 | set obj.status = 302; 59 | set obj.http.Location = "https://" + req.http.host + req.http.Location; 60 | return(deliver); 61 | } 62 | EOT 63 | } 64 | snippet { 65 | name = "redirect-numbers" 66 | type = "recv" 67 | content = <<-EOT 68 | if (req.url ~ "^/(\d|\d\d|\d\d\d|\d\d\d\d)/?$") { 69 | set req.http.Location = "/pep-" + std.strpad(re.group.1, 4, "0") + "/"; 70 | error 618; 71 | } 72 | EOT 73 | } 74 | snippet { 75 | name = "left-pad-pep-numbers" 76 | type = "recv" 77 | content = <<-EOT 78 | if (req.url ~ "^/pep-(\d|\d\d|\d\d\d)/?$") { 79 | set req.http.Location = "/pep-" + std.strpad(re.group.1, 4, "0") + "/"; 80 | error 618; 81 | } 82 | EOT 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/LICENCE.rst: -------------------------------------------------------------------------------- 1 | This files in this directory are placed in the public domain or under the 2 | CC0-1.0-Universal license, whichever is more permissive. 3 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/html/pep_html_builder.py: -------------------------------------------------------------------------------- 1 | from docutils import nodes 2 | from docutils.frontend import OptionParser 3 | from sphinx.builders.html import StandaloneHTMLBuilder 4 | from sphinx.writers.html import HTMLWriter 5 | 6 | from sphinx.builders.dirhtml import DirectoryHTMLBuilder 7 | 8 | 9 | class FileBuilder(StandaloneHTMLBuilder): 10 | copysource = False # Prevent unneeded source copying - we link direct to GitHub 11 | search = False # Disable search 12 | 13 | # Things we don't use but that need to exist: 14 | indexer = None 15 | relations = {} 16 | _script_files = _css_files = [] 17 | globalcontext = {"script_files": [], "css_files": []} 18 | 19 | def prepare_writing(self, _doc_names: set[str]) -> None: 20 | self.docwriter = HTMLWriter(self) 21 | _opt_parser = OptionParser([self.docwriter], defaults=self.env.settings, read_config_files=True) 22 | self.docsettings = _opt_parser.get_default_values() 23 | self._orig_css_files = self._orig_js_files = [] 24 | 25 | def get_doc_context(self, docname: str, body: str, _metatags: str) -> dict: 26 | """Collect items for the template context of a page.""" 27 | try: 28 | title = self.env.longtitles[docname].astext() 29 | except KeyError: 30 | title = "" 31 | 32 | # local table of contents 33 | toc_tree = self.env.tocs[docname].deepcopy() 34 | if len(toc_tree) and len(toc_tree[0]) > 1: 35 | toc_tree = toc_tree[0][1] # don't include document title 36 | del toc_tree[0] # remove contents node 37 | for node in toc_tree.findall(nodes.reference): 38 | node["refuri"] = node["anchorname"] or '#' # fix targets 39 | toc = self.render_partial(toc_tree)["fragment"] 40 | else: 41 | toc = "" # PEPs with no sections -- 9, 210 42 | 43 | return {"title": title, "toc": toc, "body": body} 44 | 45 | 46 | class DirectoryBuilder(FileBuilder): 47 | # sync all overwritten things from DirectoryHTMLBuilder 48 | name = DirectoryHTMLBuilder.name 49 | get_target_uri = DirectoryHTMLBuilder.get_target_uri 50 | get_outfilename = DirectoryHTMLBuilder.get_outfilename 51 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/parsing/pep_parser.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import TYPE_CHECKING 4 | 5 | from sphinx import parsers 6 | 7 | from pep_sphinx_extensions.pep_processor.transforms import pep_contents 8 | from pep_sphinx_extensions.pep_processor.transforms import pep_footer 9 | from pep_sphinx_extensions.pep_processor.transforms import pep_headers 10 | from pep_sphinx_extensions.pep_processor.transforms import pep_title 11 | 12 | if TYPE_CHECKING: 13 | from docutils import transforms 14 | 15 | 16 | class PEPParser(parsers.RSTParser): 17 | """RST parser with custom PEP transforms.""" 18 | 19 | supported = ("pep", "python-enhancement-proposal") # for source_suffix in conf.py 20 | 21 | def __init__(self): 22 | """Mark the document as containing RFC 2822 headers.""" 23 | super().__init__(rfc2822=True) 24 | 25 | def get_transforms(self) -> list[type[transforms.Transform]]: 26 | """Use our custom PEP transform rules.""" 27 | return [ 28 | pep_headers.PEPHeaders, 29 | pep_title.PEPTitle, 30 | pep_contents.PEPContents, 31 | pep_footer.PEPFooter, 32 | ] 33 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/parsing/pep_role.py: -------------------------------------------------------------------------------- 1 | from docutils import nodes 2 | from sphinx import roles 3 | 4 | 5 | class PEPRole(roles.ReferenceRole): 6 | """Override the :pep: role""" 7 | 8 | def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]: 9 | # Get PEP URI from role text. 10 | pep_str, _, fragment = self.target.partition("#") 11 | try: 12 | pep_num = int(pep_str) 13 | except ValueError: 14 | msg = self.inliner.reporter.error(f'invalid PEP number {self.target}', line=self.lineno) 15 | prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) 16 | return [prb], [msg] 17 | pep_base = self.inliner.document.settings.pep_url.format(pep_num) 18 | if self.inliner.document.settings.builder == "dirhtml": 19 | pep_base = "../" + pep_base 20 | if "topic" in self.get_location(): 21 | pep_base = "../" + pep_base 22 | if fragment: 23 | ref_uri = f"{pep_base}#{fragment}" 24 | else: 25 | ref_uri = pep_base 26 | if self.has_explicit_title: 27 | title = self.title 28 | else: 29 | title = f"PEP {pep_num}" 30 | 31 | return [ 32 | nodes.reference( 33 | "", title, 34 | internal=True, 35 | refuri=ref_uri, 36 | classes=["pep"], 37 | _title_tuple=(pep_num, fragment) 38 | ) 39 | ], [] 40 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/transforms/pep_contents.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | 5 | from docutils import nodes 6 | from docutils import transforms 7 | from docutils.transforms import parts 8 | 9 | 10 | class PEPContents(transforms.Transform): 11 | """Add TOC placeholder and horizontal rule after PEP title and headers.""" 12 | 13 | # Use same priority as docutils.transforms.Contents 14 | default_priority = 380 15 | 16 | def apply(self) -> None: 17 | if not Path(self.document["source"]).match("pep-*"): 18 | return # not a PEP file, exit early 19 | # Create the contents placeholder section 20 | contents_section = nodes.section("") 21 | if not self.document.has_name("contents"): 22 | contents_section["names"].append("contents") 23 | self.document.note_implicit_target(contents_section) 24 | 25 | # Add a table of contents builder 26 | pending = nodes.pending(Contents) 27 | contents_section += pending 28 | self.document.note_pending(pending) 29 | 30 | # Insert the toc after title and PEP headers 31 | self.document.children[0].insert(2, contents_section) 32 | 33 | # Add a horizontal rule before contents 34 | transition = nodes.transition() 35 | self.document[0].insert(2, transition) 36 | 37 | 38 | class Contents(parts.Contents): 39 | """Build Table of Contents from document.""" 40 | def __init__(self, document: nodes.document, startnode: nodes.Node | None = None): 41 | super().__init__(document, startnode) 42 | 43 | # used in parts.Contents.build_contents 44 | self.toc_id = None 45 | self.backlinks = None 46 | 47 | def apply(self) -> None: 48 | contents = self.build_contents(self.document[0][4:]) # skip PEP title, headers, <hr/>, and contents 49 | if contents: 50 | self.startnode.replace_self(contents) 51 | else: 52 | # if no contents, remove the empty placeholder 53 | self.startnode.parent.parent.remove(self.startnode.parent) 54 | 55 | def build_contents(self, node: nodes.Node | list[nodes.Node], _level: None = None): 56 | entries = [] 57 | children = getattr(node, "children", node) 58 | 59 | for section in children: 60 | if not isinstance(section, nodes.section): 61 | continue 62 | 63 | title = section[0] 64 | 65 | # remove all pre-existing hyperlinks in the title (e.g. PEP references) 66 | while (link_node := title.next_node(nodes.reference)) is not None: 67 | link_node.replace_self(link_node[0]) 68 | ref_id = section['ids'][0] 69 | title["refid"] = ref_id # Add a link to self 70 | entry_text = self.copy_and_filter(title) 71 | reference = nodes.reference("", "", refid=ref_id, *entry_text) 72 | item = nodes.list_item("", nodes.paragraph("", "", reference)) 73 | 74 | item += self.build_contents(section) # recurse to add sub-sections 75 | entries.append(item) 76 | if entries: 77 | return nodes.bullet_list('', *entries) 78 | return [] 79 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/transforms/pep_references.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from docutils import nodes 4 | from docutils import transforms 5 | 6 | 7 | class PEPReferenceRoleTitleText(transforms.Transform): 8 | """Add title text of document titles to reference role references.""" 9 | 10 | default_priority = 730 11 | 12 | def apply(self) -> None: 13 | if not Path(self.document["source"]).match("pep-*"): 14 | return # not a PEP file, exit early 15 | for node in self.document.findall(nodes.reference): 16 | if "_title_tuple" not in node: 17 | continue 18 | 19 | # get pep number and section target (fragment) 20 | pep_num, fragment = node.attributes.pop("_title_tuple") 21 | filename = f"pep-{pep_num:0>4}" 22 | 23 | # Cache target_ids 24 | env = self.document.settings.env 25 | try: 26 | target_ids = env.document_ids[filename] 27 | except KeyError: 28 | env.document_ids[filename] = target_ids = env.get_doctree(filename).ids 29 | 30 | # Create title text string. We hijack the 'reftitle' attribute so 31 | # that we don't have to change things in the HTML translator 32 | node["reftitle"] = env.titles[filename].astext() 33 | try: 34 | node["reftitle"] += f" § {target_ids[fragment][0].astext()}" 35 | except KeyError: 36 | pass 37 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/transforms/pep_title.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from docutils import nodes 4 | from docutils import transforms 5 | from docutils import utils 6 | from docutils.parsers.rst import roles 7 | from docutils.parsers.rst import states 8 | 9 | 10 | class PEPTitle(transforms.Transform): 11 | """Add PEP title and organise document hierarchy.""" 12 | 13 | # needs to run before docutils.transforms.frontmatter.DocInfo and after 14 | # pep_processor.transforms.pep_title.PEPTitle 15 | default_priority = 335 16 | 17 | def apply(self) -> None: 18 | if not Path(self.document["source"]).match("pep-*"): 19 | return # not a PEP file, exit early 20 | 21 | # Directory to hold the PEP's RFC2822 header details, to extract a title string 22 | pep_header_details = {} 23 | 24 | # Iterate through the header fields, which are the first section of the document 25 | desired_fields = {"PEP", "Title"} 26 | fields_to_remove = [] 27 | for field in self.document[0]: 28 | # Hold details of the attribute's tag against its details 29 | row_attributes = {sub.tagname: sub.rawsource for sub in field} 30 | pep_header_details[row_attributes["field_name"]] = row_attributes["field_body"] 31 | 32 | # Store the redundant fields in the table for removal 33 | if row_attributes["field_name"] in desired_fields: 34 | fields_to_remove.append(field) 35 | 36 | # We only need the PEP number and title 37 | if pep_header_details.keys() >= desired_fields: 38 | break 39 | 40 | # Create the title string for the PEP 41 | pep_number = int(pep_header_details["PEP"]) 42 | pep_title = pep_header_details["Title"] 43 | pep_title_string = f"PEP {pep_number} -- {pep_title}" # double hyphen for en dash 44 | 45 | # Generate the title section node and its properties 46 | title_nodes = _line_to_nodes(pep_title_string) 47 | pep_title_node = nodes.section("", nodes.title("", "", *title_nodes, classes=["page-title"]), names=["pep-content"]) 48 | 49 | # Insert the title node as the root element, move children down 50 | document_children = self.document.children 51 | self.document.children = [pep_title_node] 52 | pep_title_node.extend(document_children) 53 | self.document.note_implicit_target(pep_title_node, pep_title_node) 54 | 55 | # Remove the now-redundant fields 56 | for field in fields_to_remove: 57 | field.parent.remove(field) 58 | 59 | 60 | def _line_to_nodes(text: str) -> list[nodes.Node]: 61 | """Parse RST string to nodes.""" 62 | document = utils.new_document("<inline-rst>") 63 | document.settings.pep_references = document.settings.rfc_references = False # patch settings 64 | states.RSTStateMachine(state_classes=states.state_classes, initial_state="Body").run([text], document) # do parsing 65 | roles._roles.pop("", None) # restore the "default" default role after parsing a document 66 | return document[0].children 67 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_processor/transforms/pep_zero.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from docutils import nodes 4 | from docutils import transforms 5 | 6 | 7 | class PEPZero(transforms.Transform): 8 | """Schedule PEP 0 processing.""" 9 | 10 | # Run during sphinx post-processing 11 | default_priority = 760 12 | 13 | def apply(self) -> None: 14 | # Walk document and mask email addresses if present. 15 | for reference_node in self.document.findall(nodes.reference): 16 | reference_node.replace_self(_mask_email(reference_node)) 17 | # Remove this node 18 | self.startnode.parent.remove(self.startnode) 19 | 20 | 21 | def _mask_email(ref: nodes.reference) -> nodes.reference: 22 | """Mask the email address in `ref` and return a replacement node. 23 | 24 | `ref` is returned unchanged if it contains no email address. 25 | 26 | If given an email not explicitly whitelisted, process it such that 27 | `user@host` -> `user at host`. 28 | 29 | The returned node has no refuri link attribute. 30 | 31 | """ 32 | if not ref.get("refuri", "").startswith("mailto:"): 33 | return ref 34 | return nodes.raw("", ref[0].replace("@", " at "), format="html") 35 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/colour_scheme.js: -------------------------------------------------------------------------------- 1 | // Handle setting and changing the site's color scheme (light/dark) 2 | 3 | "use strict"; 4 | 5 | const prefersDark = window.matchMedia("(prefers-color-scheme: dark)") 6 | 7 | const getColourScheme = () => document.documentElement.dataset.colour_scheme 8 | const setColourScheme = (colourScheme = getColourScheme()) => { 9 | document.documentElement.dataset.colour_scheme = colourScheme 10 | localStorage.setItem("colour_scheme", colourScheme) 11 | setPygments(colourScheme) 12 | } 13 | 14 | // Map system theme to a cycle of steps 15 | const cycles = { 16 | dark: ["auto", "light", "dark"], // auto (dark) → light → dark 17 | light: ["auto", "dark", "light"], // auto (light) → dark → light 18 | } 19 | 20 | const nextColourScheme = (colourScheme = getColourScheme()) => { 21 | const cycle = cycles[prefersDark.matches ? "dark" : "light"] 22 | return cycle[(cycle.indexOf(colourScheme) + 1) % cycle.length] 23 | } 24 | 25 | const setPygments = (colourScheme = getColourScheme()) => { 26 | const pygmentsDark = document.getElementById("pyg-dark") 27 | const pygmentsLight = document.getElementById("pyg-light") 28 | pygmentsDark.disabled = colourScheme === "light" 29 | pygmentsLight.disabled = colourScheme === "dark" 30 | pygmentsDark.media = colourScheme === "auto" ? "(prefers-color-scheme: dark)" : "" 31 | pygmentsLight.media = colourScheme === "auto" ? "(prefers-color-scheme: light)" : "" 32 | } 33 | 34 | // Update Pygments state (the page theme is initialised inline, see page.html) 35 | document.addEventListener("DOMContentLoaded", () => setColourScheme()) 36 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/mq.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* Media Queries */ 4 | 5 | /* Reduce padding & margins for smaller screens */ 6 | @media (max-width: 40em) { 7 | section#pep-page-section { 8 | padding: 1rem; 9 | } 10 | section#pep-page-section > header > h1 { 11 | padding-right: 0; 12 | border-right: none; 13 | } 14 | ul.breadcrumbs { 15 | padding: 0 0 .5rem; 16 | } 17 | nav#pep-sidebar { 18 | display: none; 19 | } 20 | pre { 21 | font-size: 0.8175rem; 22 | } 23 | table th, 24 | table td { 25 | padding: 0 0.1rem; 26 | } 27 | } 28 | 29 | @media (min-width: 40em) { 30 | section#pep-page-section { 31 | display: table; 32 | margin: 0 auto; 33 | max-width: 75em; 34 | padding: 0.5rem 1rem 0; 35 | width: 100%; 36 | } 37 | section#pep-page-section > article { 38 | max-width: 37em; 39 | width: 74%; 40 | float: right; 41 | margin-right: 0; 42 | font-size: 1rem; 43 | } 44 | nav#pep-sidebar { 45 | width: 24%; 46 | float: left; 47 | margin-right: 2%; 48 | } 49 | /* Make less prominent when sidebar ToC is available */ 50 | details > summary { 51 | font-size: 1rem; 52 | width: max-content; 53 | } 54 | } 55 | @media (min-width: 60em) { 56 | section#pep-page-section > article { 57 | max-width: 56em; 58 | padding-left: 3.2%; 59 | padding-right: 3.2%; 60 | } 61 | } 62 | 63 | @media print { 64 | *, 65 | *:before, 66 | *:after { 67 | color: #000 !important; 68 | } 69 | body { 70 | font-size: 10pt; 71 | line-height: 1.67; 72 | } 73 | *[role="main"] a[href]:after { 74 | content: " (" attr(href) ")"; 75 | font-size: .75rem; 76 | } 77 | pre, 78 | blockquote { 79 | page-break-inside: avoid; 80 | } 81 | thead { 82 | display: table-header-group; 83 | } 84 | tr, 85 | img { 86 | page-break-inside: avoid; 87 | } 88 | img { 89 | max-width: 100% !important; 90 | } 91 | /* Page margins according to DIN 5008, leaves space for punched holes. */ 92 | @page { 93 | margin-top: 2cm; 94 | margin-bottom: 2cm; 95 | margin-left: 2.5cm; 96 | margin-right: 2.5cm; 97 | } 98 | p, 99 | h2, 100 | h3 { 101 | orphans: 3; 102 | widows: 3; 103 | } 104 | h1, 105 | h2, 106 | h3 { 107 | page-break-after: avoid; 108 | } 109 | h1 { 110 | font-size: 18pt; 111 | font-weight: bold; 112 | text-align: center; 113 | } 114 | h2, details > summary { 115 | font-size: 15pt; 116 | font-weight: normal; 117 | } 118 | h3 { 119 | font-size: 13pt; 120 | font-weight: normal; 121 | } 122 | h4 { 123 | font-size: 10pt; 124 | font-weight: 600; 125 | } 126 | a, abbr { 127 | text-decoration: none; 128 | } 129 | 130 | details { 131 | display: none; 132 | } 133 | details[open] { 134 | display: block; 135 | } 136 | 137 | h1.page-title:first-child { 138 | margin-top: 0; 139 | } 140 | 141 | section#pep-page-section { 142 | display: flex; 143 | justify-content: center; 144 | padding: 0; 145 | margin: 0 auto; 146 | } 147 | 148 | section#pep-page-section > header, 149 | nav#pep-sidebar { 150 | display: none; 151 | } 152 | 153 | section#pep-page-section > article { 154 | float: none; 155 | max-width: 17.5cm; 156 | width: auto; 157 | margin: 0; 158 | padding: 0; 159 | } 160 | 161 | /* This blocks a small portion on each page. */ 162 | readthedocs-flyout { 163 | display: none; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/pep_sphinx_extensions/pep_theme/static/og-image.png -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/pep_sphinx_extensions/pep_theme/static/py.png -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/sticky_banner.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // Inject a style element into the document head that adds scroll-margin-top to 4 | // all elements with an id attribute. This is used to offset the scroll position 5 | // when clicking on a link to an element with an id attribute. The offset is 6 | // equal to the height of the sticky banner. 7 | document.addEventListener("DOMContentLoaded", () => { 8 | const stickyBanners = document.getElementsByClassName("sticky-banner"); 9 | if (!stickyBanners.length) { 10 | return; 11 | } 12 | 13 | const stickyBanner = stickyBanners[0]; 14 | const node = document.createElement("style"); 15 | node.id = "sticky-banner-style"; 16 | document.head.appendChild(node); 17 | 18 | function adjustBannerMargin() { 19 | const text = document.createTextNode( 20 | ":target { scroll-margin-top: " + stickyBanner.offsetHeight + "px; }" 21 | ); 22 | node.replaceChildren(text); 23 | } 24 | 25 | const closeButton = document.querySelector('.close-button'); 26 | if (closeButton) { 27 | closeButton.addEventListener('click', () => { 28 | const stickyBanner = document.querySelector('.sticky-banner'); 29 | if (stickyBanner) { 30 | stickyBanner.style.display = 'none'; 31 | } 32 | }); 33 | } 34 | 35 | adjustBannerMargin(); 36 | document.addEventListener("resize", adjustBannerMargin); 37 | document.addEventListener("load", adjustBannerMargin); 38 | }); 39 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/wrap_tables.js: -------------------------------------------------------------------------------- 1 | // Wrap the tables in PEP bodies in a div, to allow for responsive scrolling 2 | 3 | "use strict"; 4 | 5 | const pepContentId = "pep-content"; 6 | 7 | 8 | // Wrap passed table element in wrapper divs 9 | function wrapTable (table) { 10 | const wrapper = document.createElement("div"); 11 | wrapper.classList.add("table-wrapper"); 12 | table.parentNode.insertBefore(wrapper, table); 13 | wrapper.appendChild(table); 14 | } 15 | 16 | 17 | // Wrap all tables in the PEP content in wrapper divs 18 | function wrapPepContentTables () { 19 | const pepContent = document.getElementById(pepContentId); 20 | const bodyTables = pepContent.getElementsByTagName("table"); 21 | Array.from(bodyTables).forEach(wrapTable); 22 | } 23 | 24 | 25 | // Wrap the tables as soon as the DOM is loaded 26 | document.addEventListener("DOMContentLoaded", () => { 27 | if (document.getElementById(pepContentId)) { 28 | wrapPepContentTables(); 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/templates/page.html: -------------------------------------------------------------------------------- 1 | {# Master template for simple pages (e.g. RST files) #} 2 | <!DOCTYPE html> 3 | <html lang="en"> 4 | <head> 5 | <meta charset="utf-8"> 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 | <meta name="color-scheme" content="light dark"> 8 | <title>{{ title + " | peps.python.org"|safe }} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% include "partials/icons.html" %} 29 | 33 |
34 |
35 |

Python Enhancement Proposals

36 | 41 | 47 |
48 |
49 | {{ body }} 50 |
51 | 59 |
60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/templates/partials/icons.html: -------------------------------------------------------------------------------- 1 | {# Adapted from Just the Docs → Furo #} 2 | 3 | 4 | Following system colour scheme 5 | 7 | 8 | 9 | 10 | 11 | 12 | Selected dark colour scheme 13 | 15 | 16 | 17 | 18 | 19 | 20 | Selected light colour scheme 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | # Theme options 3 | inherit = none 4 | pygments_style = tango 5 | pygments_dark_style = native 6 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_zero_generator/constants.py: -------------------------------------------------------------------------------- 1 | """Holds type and status constants for PEP 0 generation.""" 2 | 3 | STATUS_ACCEPTED = "Accepted" 4 | STATUS_ACTIVE = "Active" 5 | STATUS_DEFERRED = "Deferred" 6 | STATUS_DRAFT = "Draft" 7 | STATUS_FINAL = "Final" 8 | STATUS_PROVISIONAL = "Provisional" 9 | STATUS_REJECTED = "Rejected" 10 | STATUS_SUPERSEDED = "Superseded" 11 | STATUS_WITHDRAWN = "Withdrawn" 12 | 13 | # Valid values for the Status header. 14 | STATUS_VALUES = { 15 | STATUS_ACCEPTED, STATUS_PROVISIONAL, STATUS_REJECTED, STATUS_WITHDRAWN, 16 | STATUS_DEFERRED, STATUS_FINAL, STATUS_ACTIVE, STATUS_DRAFT, STATUS_SUPERSEDED, 17 | } 18 | # Map of invalid/special statuses to their valid counterparts 19 | SPECIAL_STATUSES = { 20 | "April Fool!": STATUS_REJECTED, # See PEP 401 :) 21 | } 22 | # Draft PEPs have no status displayed 23 | HIDE_STATUS = {STATUS_DRAFT} 24 | # Dead PEP statuses 25 | DEAD_STATUSES = {STATUS_REJECTED, STATUS_WITHDRAWN, STATUS_SUPERSEDED} 26 | 27 | TYPE_INFO = "Informational" 28 | TYPE_PROCESS = "Process" 29 | TYPE_STANDARDS = "Standards Track" 30 | 31 | # Valid values for the Type header. 32 | TYPE_VALUES = {TYPE_STANDARDS, TYPE_INFO, TYPE_PROCESS} 33 | # Active PEPs can only be for Informational or Process PEPs. 34 | ACTIVE_ALLOWED = {TYPE_PROCESS, TYPE_INFO} 35 | 36 | # map of topic -> additional description 37 | SUBINDICES_BY_TOPIC = { 38 | "governance": """\ 39 | These PEPs detail Python's governance, including governance model proposals 40 | and selection, and the results of the annual steering council elections. 41 | """, 42 | "packaging": """\ 43 | Packaging PEPs follow the `PyPA specification update process`_. 44 | They are used to propose major additions or changes to the PyPA specifications. 45 | The canonical, up-to-date packaging specifications can be found on the 46 | `Python Packaging Authority`_ (PyPA) `specifications`_ page. 47 | 48 | .. _Python Packaging Authority: https://www.pypa.io/ 49 | .. _specifications: https://packaging.python.org/en/latest/specifications/ 50 | .. _PyPA specification update process: https://www.pypa.io/en/latest/specifications/#specification-update-process 51 | """, 52 | "release": """\ 53 | A PEP is written to specify the release cycle for each feature release of Python. 54 | See the `developer's guide`_ for more information. 55 | 56 | .. _developer's guide: https://devguide.python.org/devcycle/ 57 | """, 58 | "typing": """\ 59 | Many recent PEPs propose changes to Python's static type system 60 | or otherwise relate to type annotations. 61 | They are listed here for reference. 62 | """, 63 | } 64 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_zero_generator/errors.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | 5 | 6 | class PEPError(Exception): 7 | def __init__(self, error: str, pep_file: Path, pep_number: int | None = None): 8 | super().__init__(error) 9 | self.filename = pep_file 10 | self.number = pep_number 11 | 12 | def __str__(self): 13 | error_msg = super(PEPError, self).__str__() 14 | error_msg = f"({self.filename}): {error_msg}" 15 | pep_str = f"PEP {self.number}" 16 | return f"{pep_str} {error_msg}" if self.number is not None else error_msg 17 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_zero_generator/pep_index_generator.py: -------------------------------------------------------------------------------- 1 | """Automatically create PEP 0 (the PEP index), 2 | 3 | This file generates and writes the PEP index to disk, ready for later 4 | processing by Sphinx. Firstly, we parse the individual PEP files, getting the 5 | RFC2822 header, and parsing and then validating that metadata. 6 | 7 | After collecting and validating all the PEP data, the creation of the index 8 | itself is in three steps: 9 | 10 | 1. Output static text. 11 | 2. Format an entry for the PEP. 12 | 3. Output the PEP (both by the category and numerical index). 13 | 14 | We then add the newly created PEP 0 file to two Sphinx environment variables 15 | to allow it to be processed as normal. 16 | 17 | """ 18 | from __future__ import annotations 19 | 20 | import json 21 | import os 22 | from pathlib import Path 23 | from typing import TYPE_CHECKING 24 | 25 | from pep_sphinx_extensions.pep_zero_generator import parser 26 | from pep_sphinx_extensions.pep_zero_generator import subindices 27 | from pep_sphinx_extensions.pep_zero_generator import writer 28 | from pep_sphinx_extensions.pep_zero_generator.constants import SUBINDICES_BY_TOPIC 29 | 30 | if TYPE_CHECKING: 31 | from sphinx.application import Sphinx 32 | from sphinx.environment import BuildEnvironment 33 | 34 | 35 | def _parse_peps(path: Path) -> list[parser.PEP]: 36 | # Read from root directory 37 | peps: list[parser.PEP] = [] 38 | 39 | for file_path in path.iterdir(): 40 | if not file_path.is_file(): 41 | continue # Skip directories etc. 42 | if file_path.match("pep-0000*"): 43 | continue # Skip pre-existing PEP 0 files 44 | if file_path.match("pep-????.rst"): 45 | pep = parser.PEP(path.joinpath(file_path).absolute()) 46 | peps.append(pep) 47 | 48 | return sorted(peps) 49 | 50 | 51 | def create_pep_json(peps: list[parser.PEP]) -> str: 52 | return json.dumps({pep.number: pep.full_details for pep in peps}, indent=1) 53 | 54 | 55 | def write_peps_json(peps: list[parser.PEP], path: Path) -> None: 56 | # Create peps.json 57 | json_peps = create_pep_json(peps) 58 | Path(path, "peps.json").write_text(json_peps, encoding="utf-8") 59 | os.makedirs(os.path.join(path, "api"), exist_ok=True) 60 | Path(path, "api", "peps.json").write_text(json_peps, encoding="utf-8") 61 | 62 | 63 | def create_pep_zero(app: Sphinx, env: BuildEnvironment, docnames: list[str]) -> None: 64 | peps = _parse_peps(Path(app.srcdir)) 65 | 66 | pep0_text = writer.PEPZeroWriter().write_pep0(peps, builder=env.settings["builder"]) 67 | pep0_path = subindices.update_sphinx("pep-0000", pep0_text, docnames, env) 68 | peps.append(parser.PEP(pep0_path)) 69 | 70 | subindices.generate_subindices(SUBINDICES_BY_TOPIC, peps, docnames, env) 71 | 72 | write_peps_json(peps, Path(app.outdir)) 73 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_zero_generator/subindices.py: -------------------------------------------------------------------------------- 1 | """Utilities to support sub-indices for PEPs.""" 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | from pathlib import Path 7 | from typing import TYPE_CHECKING 8 | 9 | from pep_sphinx_extensions.pep_zero_generator import writer 10 | 11 | if TYPE_CHECKING: 12 | from sphinx.environment import BuildEnvironment 13 | 14 | from pep_sphinx_extensions.pep_zero_generator.parser import PEP 15 | 16 | 17 | def update_sphinx(filename: str, text: str, docnames: list[str], env: BuildEnvironment) -> Path: 18 | file_path = Path(env.srcdir, f"{filename}.rst") 19 | file_path.write_text(text, encoding="utf-8") 20 | 21 | # Add to files for builder 22 | docnames.append(filename) 23 | # Add to files for writer 24 | env.found_docs.add(filename) 25 | 26 | return file_path 27 | 28 | 29 | def generate_subindices( 30 | subindices: dict[str, str], 31 | peps: list[PEP], 32 | docnames: list[str], 33 | env: BuildEnvironment, 34 | ) -> None: 35 | # create topic directory 36 | os.makedirs(os.path.join(env.srcdir, "topic"), exist_ok=True) 37 | 38 | # Create sub index page 39 | generate_topic_contents(docnames, env) 40 | 41 | for subindex, additional_description in subindices.items(): 42 | header_text = f"{subindex.title()} PEPs" 43 | header_line = "#" * len(header_text) 44 | header = header_text + "\n" + header_line + "\n" 45 | 46 | topic = subindex.lower() 47 | filtered_peps = [pep for pep in peps if topic in pep.topic] 48 | subindex_intro = f"""\ 49 | This is the index of all Python Enhancement Proposals (PEPs) labelled 50 | under the '{subindex.title()}' topic. This is a sub-index of :pep:`0`, 51 | the PEP index. 52 | 53 | {additional_description} 54 | """ 55 | subindex_text = writer.PEPZeroWriter().write_pep0( 56 | filtered_peps, header, subindex_intro, is_pep0=False, 57 | ) 58 | update_sphinx(f"topic/{subindex}", subindex_text, docnames, env) 59 | 60 | 61 | def generate_topic_contents(docnames: list[str], env: BuildEnvironment): 62 | update_sphinx("topic/index", """\ 63 | .. _topic-index: 64 | 65 | Topic Index 66 | *********** 67 | 68 | PEPs are indexed by topic on the pages below: 69 | 70 | .. toctree:: 71 | :maxdepth: 1 72 | :titlesonly: 73 | :glob: 74 | 75 | * 76 | """, docnames, env) 77 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/pep_sphinx_extensions/tests/__init__.py -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/conftest.py: -------------------------------------------------------------------------------- 1 | import importlib.util 2 | import sys 3 | from pathlib import Path 4 | 5 | _ROOT_PATH = Path(__file__, "..", "..", "..").resolve() 6 | PEP_ROOT = _ROOT_PATH / "peps" 7 | 8 | # Import "check-peps.py" as "check_peps" 9 | CHECK_PEPS_PATH = _ROOT_PATH / "check-peps.py" 10 | spec = importlib.util.spec_from_file_location("check_peps", CHECK_PEPS_PATH) 11 | sys.modules["check_peps"] = check_peps = importlib.util.module_from_spec(spec) 12 | spec.loader.exec_module(check_peps) 13 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_lint/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/pep_sphinx_extensions/tests/pep_lint/__init__.py -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_lint/test_date.py: -------------------------------------------------------------------------------- 1 | import datetime as dt 2 | 3 | import check_peps # NoQA: inserted into sys.modules in conftest.py 4 | import pytest 5 | 6 | 7 | @pytest.mark.parametrize( 8 | "line", 9 | [ 10 | # valid entries 11 | "01-Jan-2000", 12 | "29-Feb-2016", 13 | "31-Dec-2000", 14 | "01-Apr-2003", 15 | "01-Apr-2007", 16 | "01-Apr-2009", 17 | "01-Jan-1990", 18 | ], 19 | ) 20 | def test_validate_created(line: str): 21 | warnings = [warning for (_, warning) in check_peps._validate_created(1, line)] 22 | assert warnings == [], warnings 23 | 24 | 25 | @pytest.mark.parametrize( 26 | "date_str", 27 | [ 28 | # valid entries 29 | "01-Jan-2000", 30 | "29-Feb-2016", 31 | "31-Dec-2000", 32 | "01-Apr-2003", 33 | "01-Apr-2007", 34 | "01-Apr-2009", 35 | "01-Jan-1990", 36 | ], 37 | ) 38 | def test_date_checker_valid(date_str: str): 39 | warnings = [warning for (_, warning) in check_peps._date(1, date_str, "")] 40 | assert warnings == [], warnings 41 | 42 | 43 | @pytest.mark.parametrize( 44 | "date_str", 45 | [ 46 | # malformed 47 | "2000-01-01", 48 | "01 January 2000", 49 | "1 Jan 2000", 50 | "1-Jan-2000", 51 | "1-January-2000", 52 | "Jan-1-2000", 53 | "January 1 2000", 54 | "January 01 2000", 55 | "01/01/2000", 56 | "01/Jan/2000", # 🇬🇧, 🇦🇺, 🇨🇦, 🇳🇿, 🇮🇪 , ... 57 | "Jan/01/2000", # 🇺🇸 58 | "1st January 2000", 59 | "The First day of January in the year of Our Lord Two Thousand", 60 | "Jan, 1, 2000", 61 | "2000-Jan-1", 62 | "2000-Jan-01", 63 | "2000-January-1", 64 | "2000-January-01", 65 | "00 Jan 2000", 66 | "00-Jan-2000", 67 | ], 68 | ) 69 | def test_date_checker_malformed(date_str: str): 70 | warnings = [warning for (_, warning) in check_peps._date(1, date_str, "")] 71 | expected = f" must be a 'DD-mmm-YYYY' date: {date_str!r}" 72 | assert warnings == [expected], warnings 73 | 74 | 75 | @pytest.mark.parametrize( 76 | "date_str", 77 | [ 78 | # too early 79 | "31-Dec-1989", 80 | "01-Apr-1916", 81 | "01-Jan-0020", 82 | "01-Jan-0023", 83 | ], 84 | ) 85 | def test_date_checker_too_early(date_str: str): 86 | warnings = [warning for (_, warning) in check_peps._date(1, date_str, "")] 87 | expected = f" must not be before Python was invented: {date_str!r}" 88 | assert warnings == [expected], warnings 89 | 90 | 91 | @pytest.mark.parametrize( 92 | "date_str", 93 | [ 94 | # the future 95 | "31-Dec-2999", 96 | "01-Jan-2042", 97 | "01-Jan-2100", 98 | (dt.datetime.now() + dt.timedelta(days=15)).strftime("%d-%b-%Y"), 99 | (dt.datetime.now() + dt.timedelta(days=100)).strftime("%d-%b-%Y"), 100 | ], 101 | ) 102 | def test_date_checker_too_late(date_str: str): 103 | warnings = [warning for (_, warning) in check_peps._date(1, date_str, "")] 104 | expected = f" must not be in the future: {date_str!r}" 105 | assert warnings == [expected], warnings 106 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_lint/test_direct_links.py: -------------------------------------------------------------------------------- 1 | import check_peps # NoQA: inserted into sys.modules in conftest.py 2 | import pytest 3 | 4 | 5 | @pytest.mark.parametrize( 6 | "line", 7 | [ 8 | "http://www.python.org/dev/peps/pep-0000/", 9 | "https://www.python.org/dev/peps/pep-0000/", 10 | "http://peps.python.org/pep-0000/", 11 | "https://peps.python.org/pep-0000/", 12 | ], 13 | ) 14 | def test_check_direct_links_pep(line: str): 15 | warnings = [warning for (_, warning) in check_peps.check_direct_links(1, line)] 16 | assert warnings == ["Use the :pep:`NNN` role to refer to PEPs"], warnings 17 | 18 | 19 | @pytest.mark.parametrize( 20 | "line", 21 | [ 22 | "http://www.rfc-editor.org/rfc/rfc2324", 23 | "https://www.rfc-editor.org/rfc/rfc2324", 24 | "http://datatracker.ietf.org/doc/html/rfc2324", 25 | "https://datatracker.ietf.org/doc/html/rfc2324", 26 | ], 27 | ) 28 | def test_check_direct_links_rfc(line: str): 29 | warnings = [warning for (_, warning) in check_peps.check_direct_links(1, line)] 30 | assert warnings == ["Use the :rfc:`NNN` role to refer to RFCs"], warnings 31 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_lint/test_pep_lint.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import check_peps # NoQA: inserted into sys.modules in conftest.py 4 | 5 | PEP_9002 = Path(__file__).parent.parent / "peps" / "pep-9002.rst" 6 | 7 | 8 | def test_with_fake_pep(): 9 | content = PEP_9002.read_text(encoding="utf-8").splitlines() 10 | warnings = list(check_peps.check_peps(PEP_9002, content)) 11 | assert warnings == [ 12 | (1, "PEP must begin with the 'PEP:' header"), 13 | (9, "Must not have duplicate header: Sponsor "), 14 | (10, "Must not have invalid header: Horse-Guards"), 15 | (1, "Must have required header: PEP"), 16 | (1, "Must have required header: Type"), 17 | ( 18 | 1, 19 | "Headers must be in PEP 12 order. Correct order: Title, Version, " 20 | "Author, Sponsor, BDFL-Delegate, Discussions-To, Status, Topic, " 21 | "Content-Type, Requires, Created, Python-Version, Post-History, " 22 | "Resolution", 23 | ), 24 | (4, "Author continuation lines must end with a comma"), 25 | (5, "Author line must not be over-indented"), 26 | (7, "Python-Version major part must be 1, 2, or 3: 4.0"), 27 | ( 28 | 8, 29 | "Sponsor entries must begin with a valid 'Name': " 30 | r"'Sponsor:\nHorse-Guards: Parade'", 31 | ), 32 | (11, "Created must be a 'DD-mmm-YYYY' date: '1-Jan-1989'"), 33 | (12, "Delegate entries must begin with a valid 'Name': 'Barry!'"), 34 | (13, "Status must be a valid PEP status"), 35 | (14, "Topic must not contain duplicates"), 36 | (14, "Topic must be properly capitalised (Title Case)"), 37 | (14, "Topic must be for a valid sub-index"), 38 | (14, "Topic must be sorted lexicographically"), 39 | (15, "Content-Type must be 'text/x-rst'"), 40 | (16, "PEP references must be separated by comma-spaces (', ')"), 41 | (17, "Discussions-To must be a valid thread URL or mailing list"), 42 | (18, "Post-History must be a 'DD-mmm-YYYY' date: '2-Feb-2000'"), 43 | (18, "Post-History must be a valid thread URL"), 44 | (19, "Post-History must be a 'DD-mmm-YYYY' date: '3-Mar-2001'"), 45 | (19, "Post-History must be a valid thread URL"), 46 | (20, "Resolution must be a valid thread URL"), 47 | (23, "Use the :pep:`NNN` role to refer to PEPs"), 48 | ] 49 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_lint/test_pep_number.py: -------------------------------------------------------------------------------- 1 | import check_peps # NoQA: inserted into sys.modules in conftest.py 2 | import pytest 3 | 4 | 5 | @pytest.mark.parametrize( 6 | "line", 7 | [ 8 | "PEP: 0", 9 | "PEP: 12", 10 | ], 11 | ) 12 | def test_validate_pep_number(line: str): 13 | warnings = [warning for (_, warning) in check_peps._validate_pep_number(line)] 14 | assert warnings == [], warnings 15 | 16 | 17 | @pytest.mark.parametrize( 18 | "line", 19 | [ 20 | "0", 21 | "PEP:12", 22 | "PEP 0", 23 | "PEP 12", 24 | "PEP:0", 25 | ], 26 | ) 27 | def test_validate_pep_number_invalid_header(line: str): 28 | warnings = [warning for (_, warning) in check_peps._validate_pep_number(line)] 29 | assert warnings == ["PEP must begin with the 'PEP:' header"], warnings 30 | 31 | 32 | @pytest.mark.parametrize( 33 | ("pep_number", "expected_warnings"), 34 | [ 35 | # valid entries 36 | ("0", set()), 37 | ("1", set()), 38 | ("12", set()), 39 | ("20", set()), 40 | ("101", set()), 41 | ("801", set()), 42 | ("3099", set()), 43 | ("9999", set()), 44 | # empty 45 | ("", {"not blank"}), 46 | # leading zeros 47 | ("01", {"leading zeros"}), 48 | ("001", {"leading zeros"}), 49 | ("0001", {"leading zeros"}), 50 | ("00001", {"leading zeros"}), 51 | # non-numeric 52 | ("a", {"non-numeric"}), 53 | ("123abc", {"non-numeric"}), 54 | ("0123A", {"leading zeros", "non-numeric"}), 55 | ("0", {"non-numeric"}), 56 | ("101", {"non-numeric"}), 57 | ("9999", {"non-numeric"}), 58 | ("𝟎", {"non-numeric"}), 59 | ("𝟘", {"non-numeric"}), 60 | ("𝟏𝟚", {"non-numeric"}), 61 | ("𝟸𝟬", {"non-numeric"}), 62 | ("-1", {"non-numeric"}), 63 | ("+1", {"non-numeric"}), 64 | # out of bounds 65 | ("10000", {"range"}), 66 | ("54321", {"range"}), 67 | ("99999", {"range"}), 68 | ("32768", {"range"}), 69 | ], 70 | # call str() on each parameterised value in the test ID. 71 | ids=str, 72 | ) 73 | def test_pep_num_checker(pep_number: str, expected_warnings: set): 74 | warnings = [ 75 | warning for (_, warning) in check_peps._pep_num(1, pep_number, "") 76 | ] 77 | 78 | found_warnings = set() 79 | pep_number = pep_number.strip() 80 | 81 | if "not blank" in expected_warnings: 82 | found_warnings.add("not blank") 83 | expected = f" must not be blank: {pep_number!r}" 84 | matching = [w for w in warnings if w == expected] 85 | assert matching == [expected], warnings 86 | 87 | if "leading zeros" in expected_warnings: 88 | found_warnings.add("leading zeros") 89 | expected = f" must not contain leading zeros: {pep_number!r}" 90 | matching = [w for w in warnings if w == expected] 91 | assert matching == [expected], warnings 92 | 93 | if "non-numeric" in expected_warnings: 94 | found_warnings.add("non-numeric") 95 | expected = f" must be numeric: {pep_number!r}" 96 | matching = [w for w in warnings if w == expected] 97 | assert matching == [expected], warnings 98 | 99 | if "range" in expected_warnings: 100 | found_warnings.add("range") 101 | expected = f" must be between 0 and 9999: {pep_number!r}" 102 | matching = [w for w in warnings if w == expected] 103 | assert matching == [expected], warnings 104 | 105 | if expected_warnings == set(): 106 | assert warnings == [], warnings 107 | 108 | assert found_warnings == expected_warnings 109 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_processor/transform/test_pep_footer.py: -------------------------------------------------------------------------------- 1 | import datetime as dt 2 | 3 | from pep_sphinx_extensions.pep_processor.transforms import pep_footer 4 | 5 | from ...conftest import PEP_ROOT 6 | 7 | 8 | def test_add_source_link(): 9 | out = pep_footer._add_source_link(PEP_ROOT / "pep-0008.rst") 10 | 11 | assert "https://github.com/python/peps/blob/main/peps/pep-0008.rst" in str(out) 12 | 13 | 14 | def test_add_commit_history_info(): 15 | out = pep_footer._add_commit_history_info(PEP_ROOT / "pep-0008.rst") 16 | 17 | assert str(out).startswith( 18 | "Last modified: " 19 | '' 20 | ) 21 | # A variable timestamp comes next, don't test that 22 | assert str(out).endswith("") 23 | 24 | 25 | def test_add_commit_history_info_invalid(): 26 | out = pep_footer._add_commit_history_info(PEP_ROOT / "pep-not-found.rst") 27 | 28 | assert str(out) == "" 29 | 30 | 31 | def test_get_last_modified_timestamps(): 32 | out = pep_footer._get_last_modified_timestamps() 33 | 34 | assert len(out) >= 585 35 | # Should be a Unix timestamp and at least this 36 | assert dt.datetime.fromisoformat(out["pep-0008"]).timestamp() >= 1643124055 37 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_processor/transform/test_pep_zero.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from docutils import nodes 3 | 4 | from pep_sphinx_extensions.pep_processor.transforms import pep_zero 5 | 6 | 7 | @pytest.mark.parametrize( 8 | ("test_input", "expected"), 9 | [ 10 | ( 11 | nodes.reference( 12 | "", text="user@example.com", refuri="mailto:user@example.com" 13 | ), 14 | 'user at example.com', 15 | ), 16 | ( 17 | nodes.reference("", text="Introduction", refid="introduction"), 18 | 'Introduction', 19 | ), 20 | ], 21 | ) 22 | def test_generate_list_url(test_input, expected): 23 | out = pep_zero._mask_email(test_input) 24 | 25 | assert str(out) == expected 26 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_zero_generator/test_pep_index_generator.py: -------------------------------------------------------------------------------- 1 | from pep_sphinx_extensions.pep_zero_generator import parser, pep_index_generator 2 | 3 | from ..conftest import PEP_ROOT 4 | 5 | 6 | def test_create_pep_json(): 7 | peps = [parser.PEP(PEP_ROOT / "pep-0008.rst")] 8 | 9 | out = pep_index_generator.create_pep_json(peps) 10 | 11 | assert '"url": "https://peps.python.org/pep-0008/"' in out 12 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/pep_zero_generator/test_writer.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pytest 4 | 5 | from pep_sphinx_extensions.pep_zero_generator import parser, writer 6 | 7 | 8 | def test_pep_zero_writer_emit_text_newline(): 9 | pep0_writer = writer.PEPZeroWriter() 10 | pep0_writer.emit_text("my text 1") 11 | pep0_writer.emit_newline() 12 | pep0_writer.emit_text("my text 2") 13 | 14 | assert pep0_writer.output == ["my text 1", "", "my text 2"] 15 | 16 | 17 | def test_pep_zero_writer_emit_title(): 18 | pep0_writer = writer.PEPZeroWriter() 19 | pep0_writer.emit_title("My Title") 20 | pep0_writer.emit_subtitle("My Subtitle") 21 | 22 | assert pep0_writer.output == [ 23 | "My Title", 24 | "========", 25 | "", 26 | "My Subtitle", 27 | "-----------", 28 | "", 29 | ] 30 | 31 | 32 | @pytest.mark.parametrize( 33 | ("test_input", "expected"), 34 | [ 35 | ( 36 | "pep-9000.rst", 37 | { 38 | "Francis Fussyreverend": "one@example.com", 39 | "Javier Soulfulcommodore": "two@example.com", 40 | }, 41 | ), 42 | ( 43 | "pep-9001.rst", 44 | {"Francis Fussyreverend": "", "Javier Soulfulcommodore": ""}, 45 | ), 46 | ], 47 | ) 48 | def test_verify_email_addresses(test_input, expected): 49 | # Arrange 50 | peps = [parser.PEP(Path(f"pep_sphinx_extensions/tests/peps/{test_input}"))] 51 | 52 | # Act 53 | out = writer._verify_email_addresses(peps) 54 | 55 | # Assert 56 | assert out == expected 57 | 58 | 59 | def test_sort_authors(): 60 | # Arrange 61 | authors_dict = { 62 | "Zebra, Zoë": "zoe@example.com", 63 | "lowercase, laurence": "laurence@example.com", 64 | "Aardvark, Alfred": "alfred@example.com", 65 | } 66 | 67 | # Act 68 | out = writer._sort_authors(authors_dict) 69 | 70 | # Assert 71 | assert out == ["Aardvark, Alfred", "lowercase, laurence", "Zebra, Zoë"] 72 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/peps/pep-9000.rst: -------------------------------------------------------------------------------- 1 | PEP: 9000 2 | Title: Test with authors with email addresses 3 | Author: Francis Fussyreverend , 4 | Javier Soulfulcommodore 5 | Created: 20-Apr-2022 6 | Status: Draft 7 | Type: Process 8 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/peps/pep-9001.rst: -------------------------------------------------------------------------------- 1 | PEP: 9001 2 | Title: Test with authors with no email addresses 3 | Author: Francis Fussyreverend, 4 | Javier Soulfulcommodore 5 | Created: 20-Apr-2022 6 | Status: Draft 7 | Type: Process 8 | -------------------------------------------------------------------------------- /pep_sphinx_extensions/tests/peps/pep-9002.rst: -------------------------------------------------------------------------------- 1 | PEP:9002 2 | Title: Nobody expects the example PEP! 3 | Author: Cardinal Ximénez , 4 | Cardinal Biggles 5 | Cardinal Fang 6 | Version: 4.0 7 | Python-Version: 4.0 8 | Sponsor: 9 | Sponsor: 10 | Horse-Guards: Parade 11 | Created: 1-Jan-1989 12 | BDFL-Delegate: Barry! 13 | Status: Draught 14 | Topic: Inquisiting, Governance, Governance, packaging 15 | Content-Type: video/quicktime 16 | Requires: 0020,1,2,3, 7, 8 17 | Discussions-To: MR ALBERT SPIM, I,OOO,OO8 LONDON ROAD, OXFORD 18 | Post-History: `2-Feb-2000 `__ 19 | `3-Mar-2001 `__ 20 | Resolution: 21 | 22 | 23 | https://peps.python.org/pep-9002.html 24 | -------------------------------------------------------------------------------- /peps/conf.py: -------------------------------------------------------------------------------- 1 | # This file is placed in the public domain or under the 2 | # CC0-1.0-Universal license, whichever is more permissive. 3 | 4 | """Configuration for building PEPs using Sphinx.""" 5 | 6 | import os 7 | from pathlib import Path 8 | import sys 9 | 10 | _ROOT = Path(__file__).resolve().parent.parent 11 | sys.path.append(os.fspath(_ROOT)) 12 | 13 | # -- Project information ----------------------------------------------------- 14 | 15 | project = "PEPs" 16 | master_doc = "contents" 17 | 18 | # -- General configuration --------------------------------------------------- 19 | 20 | # Add any Sphinx extension module names here, as strings. 21 | extensions = [ 22 | "pep_sphinx_extensions", 23 | "sphinx.ext.extlinks", 24 | "sphinx.ext.intersphinx", 25 | "sphinx.ext.githubpages", 26 | ] 27 | 28 | # The file extensions of source files. Sphinx uses these suffixes as sources. 29 | source_suffix = { 30 | ".rst": "pep", 31 | } 32 | 33 | # List of patterns (relative to source dir) to ignore when looking for source files. 34 | include_patterns = [ 35 | # Required for Sphinx 36 | "contents.rst", 37 | # PEP files 38 | "pep-????.rst", 39 | # PEP ancillary files 40 | "pep-????/*.rst", 41 | # Documentation 42 | "docs/*.rst", 43 | ] 44 | exclude_patterns = [ 45 | # PEP Template 46 | "pep-0012/pep-NNNN.rst", 47 | ] 48 | 49 | # Warn on missing references 50 | nitpicky = True 51 | 52 | # Intersphinx configuration 53 | intersphinx_mapping = { 54 | 'python': ('https://docs.python.org/3/', None), 55 | 'packaging': ('https://packaging.python.org/en/latest/', None), 56 | 'typing': ('https://typing.readthedocs.io/en/latest/', None), 57 | 'devguide': ('https://devguide.python.org/', None), 58 | 'py3.11': ('https://docs.python.org/3.11/', None), 59 | 'py3.12': ('https://docs.python.org/3.12/', None), 60 | } 61 | intersphinx_disabled_reftypes = [] 62 | 63 | # sphinx.ext.extlinks 64 | # This config is a dictionary of external sites, 65 | # mapping unique short aliases to a base URL and a prefix. 66 | # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html 67 | extlinks = { 68 | "pypi": ("https://pypi.org/project/%s/", "%s"), 69 | } 70 | 71 | # -- Options for HTML output ------------------------------------------------- 72 | 73 | _PSE_PATH = _ROOT / "pep_sphinx_extensions" 74 | 75 | # HTML output settings 76 | html_math_renderer = "maths_to_html" # Maths rendering 77 | 78 | # Theme settings 79 | html_theme_path = [os.fspath(_PSE_PATH)] 80 | html_theme = "pep_theme" # The actual theme directory (child of html_theme_path) 81 | html_use_index = False # Disable index (we use PEP 0) 82 | html_style = "" # must be defined here or in theme.conf, but is unused 83 | html_permalinks = False # handled in the PEPContents transform 84 | html_baseurl = "https://peps.python.org" # to create the CNAME file 85 | gettext_auto_build = False # speed-ups 86 | 87 | templates_path = [os.fspath(_PSE_PATH / "pep_theme" / "templates")] # Theme template relative paths from `confdir` 88 | -------------------------------------------------------------------------------- /peps/contents.rst: -------------------------------------------------------------------------------- 1 | .. This file is placed in the public domain or under the 2 | CC0-1.0-Universal license, whichever is more permissive. 3 | 4 | Python Enhancement Proposals (PEPs) 5 | *********************************** 6 | 7 | This is an internal Sphinx page; please go to the :doc:`PEP Index `. 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 3 12 | :titlesonly: 13 | :hidden: 14 | :glob: 15 | :caption: PEP Table of Contents (needed for Sphinx): 16 | 17 | pep-* 18 | topic/* 19 | -------------------------------------------------------------------------------- /peps/pep-0002.rst: -------------------------------------------------------------------------------- 1 | PEP: 2 2 | Title: Procedure for Adding New Modules 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Brett Cannon , 6 | Martijn Faassen 7 | Status: Active 8 | Type: Process 9 | Content-Type: text/x-rst 10 | Created: 07-Jul-2001 11 | Post-History: 07-Jul-2001, 09-Mar-2002 12 | 13 | 14 | Introduction 15 | ============ 16 | 17 | The Python Standard Library contributes significantly to Python's 18 | success. The language comes with "batteries included", so it is easy 19 | for people to become productive with just the standard library alone. 20 | It is therefore important that the usefulness of the standard library 21 | be maintained. 22 | 23 | Due to the visibility and importance of the standard library, it must 24 | be maintained thoughtfully. As such, any code within it must be 25 | maintained by Python's development team which leads to a perpetual 26 | cost to each addition made. There is also added cognitive load for 27 | users in familiarizing themselves with what is in the standard 28 | library to be considered. 29 | 30 | New functionality is commonly added to the library in the form of new 31 | modules. This PEP will describe the procedure for the *addition* of 32 | new modules. :pep:`4` deals with procedures for deprecation of modules; 33 | the *removal* of old and unused modules from the standard library. 34 | 35 | 36 | Acceptance Procedure 37 | ==================== 38 | 39 | For top-level modules/packages, a PEP is required. The procedure for 40 | writing a PEP is covered in :pep:`1`. 41 | 42 | For submodules of a preexisting package in the standard library, 43 | additions are at the discretion of the general Python development team 44 | and its members. 45 | 46 | General guidance on what modules typically are accepted into the 47 | standard library, the overall process, etc. are covered in the 48 | `developer's guide `_. 49 | 50 | 51 | Maintenance Procedure 52 | ===================== 53 | 54 | Anything accepted into the standard library is expected to be 55 | primarily maintained there, within Python's development infrastructure. 56 | While some members of the development team may choose to maintain a 57 | backport of a module outside of the standard library, it is up to them 58 | to keep their external code in sync as appropriate. 59 | 60 | 61 | Copyright 62 | ========= 63 | 64 | This document has been placed in the public domain. 65 | -------------------------------------------------------------------------------- /peps/pep-0003.rst: -------------------------------------------------------------------------------- 1 | PEP: 3 2 | Title: Guidelines for Handling Bug Reports 3 | Author: Jeremy Hylton 4 | Status: Withdrawn 5 | Type: Process 6 | Created: 25-Sep-2000 7 | Post-History: 8 | 9 | .. withdrawn:: 10 | 11 | This PEP contained guidelines for handling bug reports in the Python 12 | bug tracker. It has been replaced by the 13 | `Developer's Guide description of issue triaging 14 | `_. 15 | Guidelines for people submitting Python bugs are `in the Python docs 16 | `__. 17 | 18 | Original Guidelines 19 | =================== 20 | 21 | 1. Make sure the bug category and bug group are correct. If they are 22 | correct, it is easier for someone interested in helping to find 23 | out, say, what all the open Tkinter bugs are. 24 | 25 | 2. If it's a minor feature request that you don't plan to address 26 | right away, add it to :pep:`42` or ask the owner to add it for you. 27 | If you add the bug to :pep:`42`, mark the bug as "feature request", 28 | "later", and "closed"; and add a comment to the bug saying that 29 | this is the case (mentioning the PEP explicitly). 30 | 31 | :: 32 | 33 | XXX do we prefer the tracker or PEP 42? 34 | 35 | 3. Assign the bug a reasonable priority. We don't yet have a clear 36 | sense of what each priority should mean. One rule, however, is 37 | that bugs with priority "urgent" or higher must be fixed before 38 | the next release. 39 | 40 | 4. If a bug report doesn't have enough information to allow you to 41 | reproduce or diagnose it, ask the original submitter for more 42 | information. If the original report is really thin and your email 43 | doesn't get a response after a reasonable waiting period, you can 44 | close the bug. 45 | 46 | 5. If you fix a bug, mark the status as "Fixed" and close it. In the 47 | comments, include the SVN revision numbers of the commit(s). In 48 | the SVN checkin message, include the issue number **and** a 49 | normal description of the change, mentioning the contributor if a 50 | patch was applied. 51 | 52 | 6. If you are assigned a bug that you are unable to deal with, assign 53 | it to someone else if you think they will be able to deal with it, 54 | otherwise it's probably best to unassign it. 55 | 56 | 57 | References 58 | ========== 59 | 60 | * https://bugs.python.org 61 | -------------------------------------------------------------------------------- /peps/pep-0004.rst: -------------------------------------------------------------------------------- 1 | PEP: 4 2 | Title: Deprecation of Standard Modules 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Brett Cannon , Martin von Löwis 6 | Status: Active 7 | Type: Process 8 | Content-Type: text/x-rst 9 | Created: 01-Oct-2000 10 | Post-History: 11 | 12 | 13 | Introduction 14 | ============ 15 | 16 | When new modules were added to the standard Python library in the 17 | past, it was not possible to foresee whether they would still be 18 | useful in the future. Even though Python "Comes With Batteries 19 | Included", batteries may discharge over time. Carrying old modules 20 | around is a burden on the maintainer, especially when there is no 21 | interest in the module anymore. 22 | 23 | At the same time, removing a module from the distribution is 24 | difficult, as it is not known in general whether anybody is still 25 | using it. This PEP defines a procedure for removing modules from the 26 | standard Python library. Usage of a module may be 'deprecated', which 27 | means that it may be removed from a future Python release. 28 | 29 | 30 | Procedure for declaring a module deprecated 31 | =========================================== 32 | 33 | To remove a top-level module/package from the standard library, a PEP 34 | is required. The deprecation process is outlined in :pep:`387`. 35 | 36 | For removing a submodule of a package in the standard library, 37 | :pep:`387` must be followed, but a PEP is not required. 38 | 39 | 40 | Copyright 41 | ========= 42 | 43 | This document has been placed in the public domain. 44 | -------------------------------------------------------------------------------- /peps/pep-0005.rst: -------------------------------------------------------------------------------- 1 | PEP: 5 2 | Title: Guidelines for Language Evolution 3 | Author: Paul Prescod 4 | Status: Superseded 5 | Type: Process 6 | Content-Type: text/x-rst 7 | Created: 26-Oct-2000 8 | Post-History: 9 | Superseded-By: 387 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | In the natural evolution of programming languages it is sometimes 16 | necessary to make changes that modify the behavior of older programs. 17 | This PEP proposes a policy for implementing these changes in a manner 18 | respectful of the installed base of Python users. 19 | 20 | 21 | Implementation Details 22 | ====================== 23 | 24 | Implementation of this PEP requires the addition of a formal warning 25 | and deprecation facility that will be described in another proposal. 26 | 27 | 28 | Scope 29 | ===== 30 | 31 | These guidelines apply to future versions of Python that introduce 32 | backward-incompatible behavior. Backward incompatible behavior is a 33 | major deviation in Python interpretation from an earlier behavior 34 | described in the standard Python documentation. Removal of a feature 35 | also constitutes a change of behavior. 36 | 37 | This PEP does not replace or preclude other compatibility strategies 38 | such as dynamic loading of backwards-compatible parsers. On the other 39 | hand, if execution of "old code" requires a special switch or pragma 40 | then that is indeed a change of behavior from the point of view of the 41 | user and that change should be implemented according to these 42 | guidelines. 43 | 44 | In general, common sense must prevail in the implementation of these 45 | guidelines. For instance changing "sys.copyright" does not constitute 46 | a backwards-incompatible change of behavior! 47 | 48 | 49 | Steps For Introducing Backwards-Incompatible Features 50 | ===================================================== 51 | 52 | 1. Propose backwards-incompatible behavior in a PEP. The PEP must 53 | include a section on backwards compatibility that describes in 54 | detail a plan to complete the remainder of these steps. 55 | 56 | 2. Once the PEP is accepted as a productive direction, implement an 57 | alternate way to accomplish the task previously provided by the 58 | feature that is being removed or changed. For instance if the 59 | addition operator were scheduled for removal, a new version of 60 | Python could implement an "add()" built-in function. 61 | 62 | 3. Formally deprecate the obsolete construct in the Python 63 | documentation. 64 | 65 | 4. Add an optional warning mode to the parser that will inform users 66 | when the deprecated construct is used. In other words, all 67 | programs that will behave differently in the future must trigger 68 | warnings in this mode. Compile-time warnings are preferable to 69 | runtime warnings. The warning messages should steer people from 70 | the deprecated construct to the alternative construct. 71 | 72 | 5. There must be at least a one-year transition period between the 73 | release of the transitional version of Python and the release of 74 | the backwards incompatible version. Users will have at least a 75 | year to test their programs and migrate them from use of the 76 | deprecated construct to the alternative one. 77 | -------------------------------------------------------------------------------- /peps/pep-0010.rst: -------------------------------------------------------------------------------- 1 | PEP: 10 2 | Title: Voting Guidelines 3 | Author: Barry Warsaw 4 | Status: Active 5 | Type: Process 6 | Content-Type: text/x-rst 7 | Created: 07-Mar-2002 8 | Post-History: 07-Mar-2002 9 | 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP outlines the python-dev voting guidelines. These guidelines 16 | serve to provide feedback or gauge the "wind direction" on a 17 | particular proposal, idea, or feature. They don't have a binding 18 | force. 19 | 20 | 21 | Rationale 22 | ========= 23 | 24 | When a new idea, feature, patch, etc. is floated in the Python 25 | community, either through a PEP or on the mailing lists (most likely 26 | on python-dev [1]_), it is sometimes helpful to gauge the community's 27 | general sentiment. Sometimes people just want to register their 28 | opinion of an idea. Sometimes the BDFL wants to take a straw poll. 29 | Whatever the reason, these guidelines have been adopted so as to 30 | provide a common language for developers. 31 | 32 | While opinions are (sometimes) useful, but they are never binding. 33 | Opinions that are accompanied by rationales are always valued higher 34 | than bare scores (this is especially true with -1 votes). 35 | 36 | 37 | Voting Scores 38 | ============= 39 | 40 | The scoring guidelines are loosely derived from the Apache voting 41 | procedure [2]_, with of course our own spin on things. There are 4 42 | possible vote scores: 43 | 44 | - ``+1`` I like it 45 | 46 | - ``+0`` I don't care, but go ahead 47 | 48 | - ``-0`` I don't care, so why bother? 49 | 50 | - ``-1`` I hate it 51 | 52 | You may occasionally see wild flashes of enthusiasm (either for or 53 | against) with vote scores like +2, +1000, or -1000. These aren't 54 | really valued much beyond the above scores, but it's nice to see 55 | people get excited about such geeky stuff. 56 | 57 | 58 | References 59 | ========== 60 | 61 | .. [1] Python Developer's Guide, 62 | (http://www.python.org/dev/) 63 | 64 | .. [2] Apache Project Guidelines and Voting Rules 65 | (http://httpd.apache.org/dev/guidelines.html) 66 | 67 | 68 | Copyright 69 | ========= 70 | 71 | This document has been placed in the public domain. 72 | -------------------------------------------------------------------------------- /peps/pep-0012/pep-NNNN.rst: -------------------------------------------------------------------------------- 1 | PEP: 2 | Title: 3 | Author: 4 | Sponsor: 5 | PEP-Delegate: 6 | Discussions-To: 7 | Status: 8 | Type: 9 | Topic: 10 | Requires: 11 | Created: 12 | Python-Version: 13 | Post-History: 14 | Replaces: 15 | Superseded-By: 16 | Resolution: 17 | 18 | 19 | Abstract 20 | ======== 21 | 22 | [A short (~200 word) description of the technical issue being addressed.] 23 | 24 | 25 | Motivation 26 | ========== 27 | 28 | [Clearly explain why the existing language specification is inadequate to address the problem that the PEP solves.] 29 | 30 | 31 | Rationale 32 | ========= 33 | 34 | [Describe why particular design decisions were made.] 35 | 36 | 37 | Specification 38 | ============= 39 | 40 | [Describe the syntax and semantics of any new language feature.] 41 | 42 | 43 | Backwards Compatibility 44 | ======================= 45 | 46 | [Describe potential impact and severity on pre-existing code.] 47 | 48 | 49 | Security Implications 50 | ===================== 51 | 52 | [How could a malicious user take advantage of this new feature?] 53 | 54 | 55 | How to Teach This 56 | ================= 57 | 58 | [How to teach users, new and experienced, how to apply the PEP to their work.] 59 | 60 | 61 | Reference Implementation 62 | ======================== 63 | 64 | [Link to any existing implementation and details about its state, e.g. proof-of-concept.] 65 | 66 | 67 | Rejected Ideas 68 | ============== 69 | 70 | [Why certain ideas that were brought while discussing this PEP were not ultimately pursued.] 71 | 72 | 73 | Open Issues 74 | =========== 75 | 76 | [Any points that are still being decided/discussed.] 77 | 78 | 79 | Footnotes 80 | ========= 81 | 82 | [A collection of footnotes cited in the PEP, and a place to list non-inline hyperlink targets.] 83 | 84 | 85 | Copyright 86 | ========= 87 | 88 | This document is placed in the public domain or under the 89 | CC0-1.0-Universal license, whichever is more permissive. 90 | -------------------------------------------------------------------------------- /peps/pep-0020.rst: -------------------------------------------------------------------------------- 1 | PEP: 20 2 | Title: The Zen of Python 3 | Author: Tim Peters 4 | Status: Active 5 | Type: Informational 6 | Content-Type: text/x-rst 7 | Created: 19-Aug-2004 8 | Post-History: 22-Aug-2004 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding 15 | principles for Python's design into 20 aphorisms, only 19 of which 16 | have been written down. 17 | 18 | 19 | The Zen of Python 20 | ================= 21 | 22 | .. code-block:: text 23 | 24 | Beautiful is better than ugly. 25 | Explicit is better than implicit. 26 | Simple is better than complex. 27 | Complex is better than complicated. 28 | Flat is better than nested. 29 | Sparse is better than dense. 30 | Readability counts. 31 | Special cases aren't special enough to break the rules. 32 | Although practicality beats purity. 33 | Errors should never pass silently. 34 | Unless explicitly silenced. 35 | In the face of ambiguity, refuse the temptation to guess. 36 | There should be one-- and preferably only one --obvious way to do it. 37 | Although that way may not be obvious at first unless you're Dutch. 38 | Now is better than never. 39 | Although never is often better than *right* now. 40 | If the implementation is hard to explain, it's a bad idea. 41 | If the implementation is easy to explain, it may be a good idea. 42 | Namespaces are one honking great idea -- let's do more of those! 43 | 44 | 45 | Easter Egg 46 | ========== 47 | 48 | .. code-block:: pycon 49 | 50 | >>> import this 51 | 52 | 53 | References 54 | ========== 55 | 56 | Originally posted to comp.lang.python/python-list@python.org under a 57 | thread called `"The Way of Python" 58 | `__ 59 | 60 | 61 | Copyright 62 | ========= 63 | 64 | This document has been placed in the public domain. 65 | -------------------------------------------------------------------------------- /peps/pep-0160.rst: -------------------------------------------------------------------------------- 1 | PEP: 160 2 | Title: Python 1.6 Release Schedule 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Fred L. Drake, Jr. 6 | Status: Final 7 | Type: Informational 8 | Topic: Release 9 | Content-Type: text/x-rst 10 | Created: 25-Jul-2000 11 | Python-Version: 1.6 12 | Post-History: 13 | 14 | 15 | Introduction 16 | ============ 17 | 18 | This PEP describes the Python 1.6 release schedule. The CVS 19 | revision history of this file contains the definitive historical 20 | record. 21 | 22 | This release will be produced by BeOpen PythonLabs staff for the 23 | Corporation for National Research Initiatives (CNRI). 24 | 25 | 26 | Schedule 27 | ======== 28 | 29 | * August 1: 1.6 beta 1 release (planned). 30 | * August 3: 1.6 beta 1 release (actual). 31 | * August 15: 1.6 final release (planned). 32 | * September 5: 1.6 final release (actual). 33 | 34 | 35 | Features 36 | ======== 37 | 38 | A number of features are required for Python 1.6 in order to 39 | fulfill the various promises that have been made. The following 40 | are required to be fully operational, documented, and forward 41 | compatible with the plans for Python 2.0: 42 | 43 | * Unicode support: The Unicode object defined for Python 2.0 must be provided, 44 | including all methods and codec support. 45 | 46 | * SRE: Fredrik Lundh's new regular expression engine will be used 47 | to provide support for both 8-bit strings and Unicode strings. It must pass 48 | the regression test used for the pcre-based version of the re module. 49 | 50 | * The curses module was in the middle of a transformation to a package, so the 51 | final form was adopted. 52 | 53 | 54 | Mechanism 55 | ========= 56 | 57 | The release will be created as a branch from the development tree 58 | rooted at CNRI's close of business on 16 May 2000. Patches 59 | required from more recent checkins will be merged in by moving the 60 | branch tag on individual files whenever possible in order to 61 | reduce mailing list clutter and avoid divergent and incompatible 62 | implementations. 63 | 64 | The branch tag is "cnri-16-start". 65 | 66 | Patches and features will be merged to the extent required to pass 67 | regression tests in effect on 16 May 2000. 68 | 69 | The beta release is tagged "r16b1" in the CVS repository, and the 70 | final Python 1.6 release is tagged "release16" in the repository. 71 | 72 | 73 | Copyright 74 | ========= 75 | 76 | This document has been placed in the public domain. 77 | 78 | 79 | 80 | .. 81 | Local Variables: 82 | mode: indented-text 83 | indent-tabs-mode: nil 84 | End: 85 | -------------------------------------------------------------------------------- /peps/pep-0202.rst: -------------------------------------------------------------------------------- 1 | PEP: 202 2 | Title: List Comprehensions 3 | Author: Barry Warsaw 4 | Status: Final 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 13-Jul-2000 8 | Python-Version: 2.0 9 | Post-History: 10 | 11 | 12 | Introduction 13 | ============ 14 | 15 | This PEP describes a proposed syntactical extension to Python, list 16 | comprehensions. 17 | 18 | 19 | The Proposed Solution 20 | ===================== 21 | 22 | It is proposed to allow conditional construction of list literals using for and 23 | if clauses. They would nest in the same way for loops and if statements nest 24 | now. 25 | 26 | 27 | Rationale 28 | ========= 29 | 30 | List comprehensions provide a more concise way to create lists in situations 31 | where ``map()`` and ``filter()`` and/or nested loops would currently be used. 32 | 33 | 34 | Examples 35 | ======== 36 | 37 | :: 38 | 39 | >>> print [i for i in range(10)] 40 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 41 | 42 | >>> print [i for i in range(20) if i%2 == 0] 43 | [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 44 | 45 | >>> nums = [1, 2, 3, 4] 46 | >>> fruit = ["Apples", "Peaches", "Pears", "Bananas"] 47 | >>> print [(i, f) for i in nums for f in fruit] 48 | [(1, 'Apples'), (1, 'Peaches'), (1, 'Pears'), (1, 'Bananas'), 49 | (2, 'Apples'), (2, 'Peaches'), (2, 'Pears'), (2, 'Bananas'), 50 | (3, 'Apples'), (3, 'Peaches'), (3, 'Pears'), (3, 'Bananas'), 51 | (4, 'Apples'), (4, 'Peaches'), (4, 'Pears'), (4, 'Bananas')] 52 | >>> print [(i, f) for i in nums for f in fruit if f[0] == "P"] 53 | [(1, 'Peaches'), (1, 'Pears'), 54 | (2, 'Peaches'), (2, 'Pears'), 55 | (3, 'Peaches'), (3, 'Pears'), 56 | (4, 'Peaches'), (4, 'Pears')] 57 | >>> print [(i, f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1] 58 | [(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')] 59 | >>> print [i for i in zip(nums, fruit) if i[0]%2==0] 60 | [(2, 'Peaches'), (4, 'Bananas')] 61 | 62 | 63 | Reference Implementation 64 | ======================== 65 | 66 | List comprehensions become part of the Python language with release 2.0, 67 | documented in [1]_. 68 | 69 | 70 | BDFL Pronouncements 71 | =================== 72 | * The syntax proposed above is the Right One. 73 | 74 | * The form ``[x, y for ...]`` is disallowed; one is required to write 75 | ``[(x, y) for ...]``. 76 | 77 | * The form ``[... for x... for y...]`` nests, with the last index 78 | varying fastest, just like nested for loops. 79 | 80 | 81 | References 82 | ========== 83 | 84 | .. [1] http://docs.python.org/reference/expressions.html#list-displays 85 | -------------------------------------------------------------------------------- /peps/pep-0206.rst: -------------------------------------------------------------------------------- 1 | PEP: 206 2 | Title: Python Advanced Library 3 | Author: A.M. Kuchling 4 | Status: Withdrawn 5 | Type: Informational 6 | Created: 14-Jul-2000 7 | Post-History: 8 | 9 | .. withdrawn:: 10 | 11 | Introduction 12 | ============ 13 | 14 | This PEP describes the Python Advanced Library, a collection of 15 | high-quality and frequently-used third party extension modules. 16 | 17 | 18 | Batteries Included Philosophy 19 | ============================= 20 | 21 | The Python source distribution has long maintained the philosophy 22 | of "batteries included" -- having a rich and versatile standard 23 | library which is immediately available, without making the user 24 | download separate packages. This gives the Python language a head 25 | start in many projects. 26 | 27 | However, the standard library modules aren't always the best 28 | choices for a job. Some library modules were quick hacks 29 | (e.g. ``calendar``, ``commands``), some were designed poorly and are now 30 | near-impossible to fix (``cgi``), and some have been rendered obsolete 31 | by other, more complete modules (``binascii`` offers the same features 32 | as the ``binhex``, ``uu``, ``base64`` modules). This PEP describes a list of 33 | third-party modules that make Python more competitive for various 34 | application domains, forming the Python Advanced Library. 35 | 36 | The deliverable is a set of scripts that will retrieve, build, and 37 | install the packages for a particular application domain. The 38 | Python Package Index now contains enough information to let 39 | software automatically find packages and download them, so the 40 | time is ripe to implement this. 41 | 42 | Currently this document doesn't suggest *removing* modules from 43 | the standard library that are superseded by a third-party module. 44 | That's difficult to do because it entails many backward-compatibility 45 | problems, so it's not worth bothering with now. 46 | 47 | Please suggest additional domains of interest. 48 | 49 | 50 | Domain: Web tasks 51 | ================= 52 | 53 | XML parsing: ElementTree + SAX. 54 | 55 | URL retrieval: libcurl? other possibilities? 56 | 57 | HTML parsing: mxTidy? HTMLParser? 58 | 59 | Async network I/O: Twisted 60 | 61 | RDF parser: ??? 62 | 63 | HTTP serving: ??? 64 | 65 | HTTP cookie processing: ??? 66 | 67 | Web framework: A WSGI gateway, perhaps? Paste? 68 | 69 | Graphics: PIL, Chaco. 70 | 71 | 72 | Domain: Scientific Programming 73 | ============================== 74 | 75 | Numeric: Numeric, SciPy 76 | 77 | Graphics: PIL, Chaco. 78 | 79 | 80 | Domain: Application Development 81 | =============================== 82 | 83 | GUI toolkit: ??? 84 | 85 | Graphics: Reportlab for PDF generation. 86 | 87 | 88 | Domain: Education 89 | ================= 90 | 91 | Graphics: PyGame 92 | 93 | 94 | Software covered by the GNU General Public License 95 | ================================================== 96 | 97 | Some of these third-party modules are covered by the GNU General 98 | Public License and the GNU Lesser General Public License. 99 | Providing a script to download and install such packages, or even 100 | assembling all these packages into a single tarball or CD-ROM, 101 | shouldn't cause any difficulties with the GPL, under the "mere 102 | aggregation" clause of the license. 103 | 104 | 105 | Open Issues 106 | =========== 107 | 108 | What other application domains are important? 109 | 110 | Should this just be a set of Ubuntu or Debian packages? Compiling 111 | things such as PyGame can be very complicated and may be too 112 | difficult to automate. 113 | 114 | 115 | Acknowledgements 116 | ================ 117 | 118 | The PEP is based on an earlier draft PEP by Moshe Zadka, titled 119 | "2.0 Batteries Included." 120 | -------------------------------------------------------------------------------- /peps/pep-0210.rst: -------------------------------------------------------------------------------- 1 | PEP: 210 2 | Title: Decoupling the Interpreter Loop 3 | Author: David Ascher 4 | Status: Rejected 5 | Type: Standards Track 6 | Created: 15-Jul-2000 7 | Python-Version: 2.1 8 | Post-History: 9 | 10 | .. rejected:: 11 | -------------------------------------------------------------------------------- /peps/pep-0217.rst: -------------------------------------------------------------------------------- 1 | PEP: 217 2 | Title: Display Hook for Interactive Use 3 | Author: Moshe Zadka 4 | Status: Final 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 31-Jul-2000 8 | Python-Version: 2.1 9 | Post-History: 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | Python's interactive mode is one of the implementation's great 16 | strengths -- being able to write expressions on the command line 17 | and get back a meaningful output. However, the output function 18 | cannot be all things to all people, and the current output 19 | function too often falls short of this goal. This PEP describes a 20 | way to provides alternatives to the built-in display function in 21 | Python, so users will have control over the output from the 22 | interactive interpreter. 23 | 24 | 25 | Interface 26 | ========= 27 | 28 | The current Python solution has worked for many users, and this 29 | should not break it. Therefore, in the default configuration, 30 | nothing will change in the REPL loop. To change the way the 31 | interpreter prints interactively entered expressions, users 32 | will have to rebind ``sys.displayhook`` to a callable object. 33 | The result of calling this object with the result of the 34 | interactively entered expression should be print-able, 35 | and this is what will be printed on ``sys.stdout``. 36 | 37 | 38 | Solution 39 | ======== 40 | 41 | The bytecode ``PRINT_EXPR`` will call ``sys.displayhook(POP())``. 42 | A ``displayhook()`` will be added to the sys builtin module, which is 43 | equivalent to:: 44 | 45 | import __builtin__ 46 | def displayhook(o): 47 | if o is None: 48 | return 49 | __builtin__._ = None 50 | print `o` 51 | __builtin__._ = o 52 | 53 | 54 | Jython Issues 55 | ============= 56 | 57 | The method ``Py.printResult`` will be similarly changed. 58 | -------------------------------------------------------------------------------- /peps/pep-0220.rst: -------------------------------------------------------------------------------- 1 | PEP: 220 2 | Title: Coroutines, Generators, Continuations 3 | Author: Gordon McMillan 4 | Status: Rejected 5 | Type: Informational 6 | Created: 14-Aug-2000 7 | Post-History: 8 | 9 | .. rejected:: 10 | 11 | Abstract 12 | ======== 13 | 14 | Demonstrates why the changes described in the stackless PEP are 15 | desirable. A low-level continuations module exists. With it, 16 | coroutines and generators and "green" threads can be written. A 17 | higher level module that makes coroutines and generators easy to 18 | create is desirable (and being worked on). The focus of this PEP 19 | is on showing how coroutines, generators, and green threads can 20 | simplify common programming problems. 21 | -------------------------------------------------------------------------------- /peps/pep-0233.rst: -------------------------------------------------------------------------------- 1 | PEP: 233 2 | Title: Python Online Help 3 | Author: Paul Prescod 4 | Status: Deferred 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 11-Dec-2000 8 | Python-Version: 2.1 9 | Post-History: 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP describes a command-line driven online help facility for 16 | Python. The facility should be able to build on existing 17 | documentation facilities such as the Python documentation and 18 | docstrings. It should also be extensible for new types and 19 | modules. 20 | 21 | 22 | Interactive use 23 | =============== 24 | 25 | Simply typing ``help`` describes the help function (through ``repr()`` 26 | overloading). 27 | 28 | ``help`` can also be used as a function. 29 | 30 | The function takes the following forms of input: 31 | 32 | * ``help( "string" )`` -- built-in topic or global 33 | * ``help( )`` -- docstring from object or type 34 | * ``help( "doc:filename" )`` -- filename from Python documentation 35 | 36 | If you ask for a global, it can be a fully-qualified name, such as:: 37 | 38 | help("xml.dom") 39 | 40 | You can also use the facility from a command-line:: 41 | 42 | python --help if 43 | 44 | In either situation, the output does paging similar to the ``more`` 45 | command. 46 | 47 | 48 | Implementation 49 | ============== 50 | 51 | The help function is implemented in an ``onlinehelp`` module which is 52 | demand-loaded. 53 | 54 | There should be options for fetching help information from 55 | environments other than the command line through the ``onlinehelp`` 56 | module:: 57 | 58 | onlinehelp.gethelp(object_or_string) -> string 59 | 60 | It should also be possible to override the help display function 61 | by assigning to ``onlinehelp.displayhelp(object_or_string)``. 62 | 63 | The module should be able to extract module information from 64 | either the HTML or LaTeX versions of the Python documentation. 65 | Links should be accommodated in a "lynx-like" manner. 66 | 67 | Over time, it should also be able to recognize when docstrings are 68 | in "special" syntaxes like structured text, HTML and LaTeX and 69 | decode them appropriately. 70 | 71 | A prototype implementation is available with the Python source 72 | distribution as ``nondist/sandbox/doctools/onlinehelp.py``. 73 | 74 | 75 | Built-in Topics 76 | =============== 77 | 78 | * ``help( "intro" )`` -- What is Python? Read this first! 79 | 80 | * ``help( "keywords" )`` -- What are the keywords? 81 | 82 | * ``help( "syntax" )`` -- What is the overall syntax? 83 | 84 | * ``help( "operators" )`` -- What operators are available? 85 | 86 | * ``help( "builtins" )`` -- What functions, types, etc. are built-in? 87 | 88 | * ``help( "modules" )`` -- What modules are in the standard library? 89 | 90 | * ``help( "copyright" )`` -- Who owns Python? 91 | 92 | * ``help( "moreinfo" )`` -- Where is there more information? 93 | 94 | * ``help( "changes" )`` -- What changed in Python 2.0? 95 | 96 | * ``help( "extensions" )`` -- What extensions are installed? 97 | 98 | * ``help( "faq" )`` -- What questions are frequently asked? 99 | 100 | * ``help( "ack" )`` -- Who has done work on Python lately? 101 | 102 | 103 | Security Issues 104 | =============== 105 | 106 | This module will attempt to import modules with the same names as 107 | requested topics. Don't use the modules if you are not confident 108 | that everything in your ``PYTHONPATH`` is from a trusted source. 109 | -------------------------------------------------------------------------------- /peps/pep-0240.rst: -------------------------------------------------------------------------------- 1 | PEP: 240 2 | Title: Adding a Rational Literal to Python 3 | Author: Christopher A. Craig , Moshe Zadka 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 11-Mar-2001 8 | Python-Version: 2.2 9 | Post-History: 16-Mar-2001 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | A :pep:`different PEP <239>` suggests adding a builtin rational type to 16 | Python. This PEP suggests changing the ddd.ddd float literal to a 17 | rational in Python, and modifying non-integer division to return 18 | it. 19 | 20 | 21 | BDFL Pronouncement 22 | ================== 23 | 24 | This PEP is rejected. The needs outlined in the rationale section 25 | have been addressed to some extent by the acceptance of :pep:`327` 26 | for decimal arithmetic. Guido also noted, "Rational arithmetic 27 | was the default 'exact' arithmetic in ABC and it did not work out as 28 | expected". See the python-dev discussion on 17 June 2005 [1]_. 29 | 30 | 31 | Rationale 32 | ========= 33 | 34 | Rational numbers are useful for exact and unsurprising arithmetic. 35 | They give the correct results people have been taught in various 36 | math classes. Making the "obvious" non-integer type one with more 37 | predictable semantics will surprise new programmers less than 38 | using floating point numbers. As quite a few posts on c.l.py and 39 | on tutor@python.org have shown, people often get bit by strange 40 | semantics of floating point numbers: for example, ``round(0.98, 2)`` 41 | still gives 0.97999999999999998. 42 | 43 | 44 | Proposal 45 | ======== 46 | 47 | Literals conforming to the regular expression ``'\d*.\d*'`` will be 48 | rational numbers. 49 | 50 | 51 | Backwards Compatibility 52 | ======================= 53 | 54 | The only backwards compatible issue is the type of literals 55 | mentioned above. The following migration is suggested: 56 | 57 | 1. The next Python after approval will allow 58 | ``from __future__ import rational_literals`` 59 | to cause all such literals to be treated as rational numbers. 60 | 61 | 2. Python 3.0 will have a warning, turned on by default, about 62 | such literals in the absence of a ``__future__`` statement. The 63 | warning message will contain information about the ``__future__`` 64 | statement, and indicate that to get floating point literals, 65 | they should be suffixed with "e0". 66 | 67 | 3. Python 3.1 will have the warning turned off by default. This 68 | warning will stay in place for 24 months, at which time the 69 | literals will be rationals and the warning will be removed. 70 | 71 | 72 | Common Objections 73 | ================= 74 | 75 | Rationals are slow and memory intensive! 76 | (Relax, I'm not taking floats away, I'm just adding two more characters. 77 | ``1e0`` will still be a float) 78 | 79 | Rationals must present themselves as a decimal float or they will be 80 | horrible for users expecting decimals (i.e. ``str(.5)`` should return ``'.5'`` and 81 | not ``'1/2'``). This means that many rationals must be truncated at some 82 | point, which gives us a new loss of precision. 83 | 84 | 85 | 86 | References 87 | ========== 88 | 89 | .. [1] Raymond Hettinger, Propose rejection of PEPs 239 and 240 -- a builtin 90 | rational type and rational literals 91 | https://mail.python.org/pipermail/python-dev/2005-June/054281.html 92 | 93 | 94 | Copyright 95 | ========= 96 | 97 | This document has been placed in the public domain. 98 | -------------------------------------------------------------------------------- /peps/pep-0251.rst: -------------------------------------------------------------------------------- 1 | PEP: 251 2 | Title: Python 2.2 Release Schedule 3 | Author: Barry Warsaw , Guido van Rossum 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Content-Type: text/x-rst 8 | Created: 17-Apr-2001 9 | Python-Version: 2.2 10 | Post-History: 14-Aug-2001 11 | 12 | 13 | Abstract 14 | ======== 15 | 16 | This document describes the Python 2.2 development and release 17 | schedule. The schedule primarily concerns itself with PEP-sized 18 | items. Small bug fixes and changes will occur up until the first 19 | beta release. 20 | 21 | The schedule below represents the actual release dates of Python 22 | 2.2. Note that any subsequent maintenance releases of Python 2.2 23 | should be covered by separate PEPs. 24 | 25 | 26 | Release Schedule 27 | ================ 28 | 29 | Tentative future release dates. Note that we've slipped this 30 | compared to the schedule posted around the release of 2.2a1. 31 | 32 | * 21-Dec-2001: 2.2 [Released] (final release) 33 | * 14-Dec-2001: 2.2c1 [Released] 34 | * 14-Nov-2001: 2.2b2 [Released] 35 | * 19-Oct-2001: 2.2b1 [Released] 36 | * 28-Sep-2001: 2.2a4 [Released] 37 | * 7-Sep-2001: 2.2a3 [Released] 38 | * 22-Aug-2001: 2.2a2 [Released] 39 | * 18-Jul-2001: 2.2a1 [Released] 40 | 41 | 42 | Release Manager 43 | =============== 44 | 45 | Barry Warsaw was the Python 2.2 release manager. 46 | 47 | 48 | Release Mechanics 49 | ================= 50 | 51 | We experimented with a new mechanism for releases: a week before 52 | every alpha, beta or other release, we forked off a branch which 53 | became the release. Changes to the branch are limited to the 54 | release manager and his designated 'bots. This experiment was 55 | deemed a success and should be observed for future releases. See 56 | :pep:`101` for the actual release mechanics. 57 | 58 | 59 | New features for Python 2.2 60 | =========================== 61 | 62 | The following new features are introduced in Python 2.2. For a 63 | more detailed account, see Misc/NEWS [2]_ in the Python 64 | distribution, or Andrew Kuchling's "What's New in Python 2.2" 65 | document [3]_. 66 | 67 | - iterators (:pep:`234`) 68 | - generators (:pep:`255`) 69 | - unifying long ints and plain ints (:pep:`237`) 70 | - division (:pep:`238`) 71 | - unification of types and classes (:pep:`252`, :pep:`253`) 72 | 73 | 74 | References 75 | ========== 76 | 77 | .. [2] Misc/NEWS file from CVS 78 | http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/dist/src/Misc/NEWS?rev=1.337.2.4&content-type=text/vnd.viewcvs-markup 79 | 80 | .. [3] Andrew Kuchling, What's New in Python 2.2 81 | http://www.python.org/doc/2.2.1/whatsnew/whatsnew22.html 82 | 83 | 84 | Copyright 85 | ========= 86 | 87 | This document has been placed in the public domain. 88 | -------------------------------------------------------------------------------- /peps/pep-0254.rst: -------------------------------------------------------------------------------- 1 | PEP: 254 2 | Title: Making Classes Look More Like Types 3 | Author: Guido van Rossum 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 18-Jun-2001 8 | Python-Version: 2.2 9 | Post-History: 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP has not been written yet. Watch this space! 16 | 17 | 18 | Status 19 | ====== 20 | 21 | This PEP was a stub entry and eventually abandoned without having 22 | been filled-out. Substantially most of the intended functionality 23 | was implemented in Py2.2 with new-style types and classes. 24 | 25 | 26 | Copyright 27 | ========= 28 | 29 | This document has been placed in the public domain. 30 | -------------------------------------------------------------------------------- /peps/pep-0260.rst: -------------------------------------------------------------------------------- 1 | PEP: 260 2 | Title: Simplify xrange() 3 | Author: Guido van Rossum 4 | Status: Final 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 26-Jun-2001 8 | Python-Version: 2.2 9 | Post-History: 26-Jun-2001 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP proposes to strip the ``xrange()`` object from some rarely 16 | used behavior like ``x[i:j]`` and ``x*n``. 17 | 18 | 19 | Problem 20 | ======= 21 | 22 | The ``xrange()`` function has one idiomatic use:: 23 | 24 | for i in xrange(...): ... 25 | 26 | However, the ``xrange()`` object has a bunch of rarely used behaviors 27 | that attempt to make it more sequence-like. These are so rarely 28 | used that historically they have has serious bugs (e.g. off-by-one 29 | errors) that went undetected for several releases. 30 | 31 | I claim that it's better to drop these unused features. This will 32 | simplify the implementation, testing, and documentation, and 33 | reduce maintenance and code size. 34 | 35 | 36 | Proposed Solution 37 | ================= 38 | 39 | I propose to strip the ``xrange()`` object to the bare minimum. The 40 | only retained sequence behaviors are ``x[i]``, ``len(x)``, and ``repr(x)``. 41 | In particular, these behaviors will be dropped: 42 | 43 | * ``x[i:j]`` (slicing) 44 | * ``x*n``, ``n*x`` (sequence-repeat) 45 | * ``cmp(x1, x2)`` (comparisons) 46 | * ``i in x`` (containment test) 47 | * ``x.tolist()`` method 48 | * ``x.start``, ``x.stop``, ``x.step`` attributes 49 | 50 | I also propose to change the signature of the ``PyRange_New()`` C API 51 | to remove the 4th argument (the repetition count). 52 | 53 | By implementing a custom iterator type, we could speed up the 54 | common use, but this is optional (the default sequence iterator 55 | does just fine). 56 | 57 | 58 | Scope 59 | ===== 60 | 61 | This PEP affects the ``xrange()`` built-in function and the 62 | ``PyRange_New()`` C API. 63 | 64 | 65 | Risks 66 | ===== 67 | 68 | Somebody's code could be relying on the extended code, and this 69 | code would break. However, given that historically bugs in the 70 | extended code have gone undetected for so long, it's unlikely that 71 | much code is affected. 72 | 73 | 74 | Transition 75 | ========== 76 | 77 | For backwards compatibility, the existing functionality will still 78 | be present in Python 2.2, but will trigger a warning. A year 79 | after Python 2.2 final is released (probably in 2.4) the 80 | functionality will be ripped out. 81 | 82 | 83 | Copyright 84 | ========= 85 | 86 | This document has been placed in the public domain. 87 | -------------------------------------------------------------------------------- /peps/pep-0270.rst: -------------------------------------------------------------------------------- 1 | PEP: 270 2 | Title: uniq method for list objects 3 | Author: Jason Petrone 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 21-Aug-2001 8 | Python-Version: 2.2 9 | Post-History: 10 | 11 | 12 | Notice 13 | ====== 14 | 15 | This PEP is withdrawn by the author. He writes: 16 | 17 | Removing duplicate elements from a list is a common task, but 18 | there are only two reasons I can see for making it a built-in. 19 | The first is if it could be done much faster, which isn't the 20 | case. The second is if it makes it significantly easier to 21 | write code. The introduction of ``sets.py`` eliminates this 22 | situation since creating a sequence without duplicates is just 23 | a matter of choosing a different data structure: a set instead 24 | of a list. 25 | 26 | As described in :pep:`218`, sets are being added to the standard 27 | library for Python 2.3. 28 | 29 | 30 | Abstract 31 | ======== 32 | 33 | This PEP proposes adding a method for removing duplicate elements to 34 | the list object. 35 | 36 | 37 | Rationale 38 | ========= 39 | 40 | Removing duplicates from a list is a common task. I think it is 41 | useful and general enough to belong as a method in list objects. 42 | It also has potential for faster execution when implemented in C, 43 | especially if optimization using hashing or sorted cannot be used. 44 | 45 | On comp.lang.python there are many, many, posts [1]_ asking about 46 | the best way to do this task. It's a little tricky to implement 47 | optimally and it would be nice to save people the trouble of 48 | figuring it out themselves. 49 | 50 | 51 | Considerations 52 | ============== 53 | 54 | Tim Peters suggests trying to use a hash table, then trying to 55 | sort, and finally falling back on brute force [2]_. Should uniq 56 | maintain list order at the expense of speed? 57 | 58 | Is it spelled 'uniq' or 'unique'? 59 | 60 | 61 | Reference Implementation 62 | ======================== 63 | 64 | I've written the brute force version. It's about 20 lines of code 65 | in ``listobject.c``. Adding support for hash table and sorted 66 | duplicate removal would only take another hour or so. 67 | 68 | 69 | References 70 | ========== 71 | 72 | .. [1] https://groups.google.com/forum/#!searchin/comp.lang.python/duplicates 73 | 74 | .. [2] Tim Peters unique() entry in the Python cookbook: 75 | http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560/index_txt 76 | 77 | 78 | Copyright 79 | ========= 80 | 81 | This document has been placed in the public domain. 82 | -------------------------------------------------------------------------------- /peps/pep-0271.rst: -------------------------------------------------------------------------------- 1 | PEP: 271 2 | Title: Prefixing sys.path by command line option 3 | Author: Frédéric B. Giacometti 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 15-Aug-2001 8 | Python-Version: 2.2 9 | Post-History: 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | At present, setting the ``PYTHONPATH`` environment variable is the 16 | only method for defining additional Python module search 17 | directories. 18 | 19 | This PEP introduces the '-P' valued option to the python command 20 | as an alternative to ``PYTHONPATH``. 21 | 22 | 23 | Rationale 24 | ========= 25 | 26 | On Unix:: 27 | 28 | python -P $SOMEVALUE 29 | 30 | will be equivalent to:: 31 | 32 | env PYTHONPATH=$SOMEVALUE python 33 | 34 | On Windows 2K:: 35 | 36 | python -P %SOMEVALUE% 37 | 38 | will (almost) be equivalent to:: 39 | 40 | set __PYTHONPATH=%PYTHONPATH% && set PYTHONPATH=%SOMEVALUE%\ 41 | && python && set PYTHONPATH=%__PYTHONPATH% 42 | 43 | 44 | Other Information 45 | ================= 46 | 47 | This option is equivalent to the 'java -classpath' option. 48 | 49 | 50 | When to use this option 51 | ======================= 52 | 53 | This option is intended to ease and make more robust the use of 54 | Python in test or build scripts, for instance. 55 | 56 | 57 | Reference Implementation 58 | ======================== 59 | 60 | A patch implementing this is available from SourceForge:: 61 | 62 | http://sourceforge.net/tracker/download.php?group_id=5470&atid=305470&file_id=6916&aid=429614 63 | 64 | with the patch discussion at:: 65 | 66 | http://sourceforge.net/tracker/?func=detail&atid=305470&aid=429614&group_id=5470 67 | 68 | 69 | Copyright 70 | ========= 71 | 72 | This document has been placed in the public domain. 73 | -------------------------------------------------------------------------------- /peps/pep-0294.rst: -------------------------------------------------------------------------------- 1 | PEP: 294 2 | Title: Type Names in the types Module 3 | Author: Oren Tirosh 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 19-Jun-2002 8 | Python-Version: 2.5 9 | Post-History: 10 | 11 | 12 | 13 | Abstract 14 | ======== 15 | 16 | This PEP proposes that symbols matching the type name should be added 17 | to the types module for all basic Python types in the types module:: 18 | 19 | types.IntegerType -> types.int 20 | types.FunctionType -> types.function 21 | types.TracebackType -> types.traceback 22 | ... 23 | 24 | The long capitalized names currently in the types module will be 25 | deprecated. 26 | 27 | With this change the types module can serve as a replacement for the 28 | new module. The new module shall be deprecated and listed in :pep:`4`. 29 | 30 | 31 | Pronouncement 32 | ============= 33 | 34 | A centralized repository of type names was a mistake. Neither the 35 | "types" nor "new" modules should be carried forward to Python 3.0. 36 | 37 | In the meantime, it does not make sense to make the proposed updates 38 | to the modules. This would cause disruption without any compensating 39 | benefit. 40 | 41 | Instead, the problem that some internal types (frames, functions, 42 | etc.) don't live anywhere outside those modules may be addressed by 43 | either adding them to ``__builtin__`` or sys. This will provide a 44 | smoother transition to Python 3.0. 45 | 46 | 47 | Rationale 48 | ========= 49 | 50 | Using two sets of names for the same objects is redundant and 51 | confusing. 52 | 53 | In Python versions prior to 2.2 the symbols matching many type names 54 | were taken by the factory functions for those types. Now all basic 55 | types have been unified with their factory functions and therefore the 56 | type names are available to be consistently used to refer to the type 57 | object. 58 | 59 | Most types are accessible as either builtins or in the new module but 60 | some types such as traceback and generator are only accessible through 61 | the types module under names which do not match the type name. This 62 | PEP provides a uniform way to access all basic types under a single 63 | set of names. 64 | 65 | 66 | Specification 67 | ============= 68 | 69 | The types module shall pass the following test:: 70 | 71 | import types 72 | for t in vars(types).values(): 73 | if type(t) is type: 74 | assert getattr(types, t.__name__) is t 75 | 76 | The types 'class', 'instance method' and 'dict-proxy' have already 77 | been renamed to the valid Python identifiers 'classobj', 78 | 'instancemethod' and 'dictproxy', making this possible. 79 | 80 | 81 | Backward compatibility 82 | ====================== 83 | 84 | Because of their widespread use it is not planned to actually remove 85 | the long names from the types module in some future version. However, 86 | the long names should be changed in documentation and library sources 87 | to discourage their use in new code. 88 | 89 | 90 | Reference Implementation 91 | ======================== 92 | 93 | A reference implementation is available in 94 | `issue #569328 `_. 95 | 96 | 97 | Copyright 98 | ========= 99 | 100 | This document has been placed in the public domain. 101 | -------------------------------------------------------------------------------- /peps/pep-0295.rst: -------------------------------------------------------------------------------- 1 | PEP: 295 2 | Title: Interpretation of multiline string constants 3 | Author: Stepan Koltsov 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 22-Jul-2002 8 | Python-Version: 3.0 9 | Post-History: 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP describes an interpretation of multiline string constants 16 | for Python. It suggests stripping spaces after newlines and 17 | stripping a newline if it is first character after an opening 18 | quotation. 19 | 20 | 21 | Rationale 22 | ========= 23 | 24 | This PEP proposes an interpretation of multiline string constants 25 | in Python. Currently, the value of string constant is all the 26 | text between quotations, maybe with escape sequences substituted, 27 | e.g.:: 28 | 29 | def f(): 30 | """ 31 | la-la-la 32 | limona, banana 33 | """ 34 | 35 | def g(): 36 | return "This is \ 37 | string" 38 | 39 | print repr(f.__doc__) 40 | print repr(g()) 41 | 42 | prints:: 43 | 44 | '\n\tla-la-la\n\tlimona, banana\n\t' 45 | 'This is \tstring' 46 | 47 | This PEP suggest two things: 48 | 49 | - ignore the first character after opening quotation, if it is 50 | newline 51 | 52 | - ignore in string constants all spaces and tabs up to 53 | first non-whitespace character, but no more than current 54 | indentation. 55 | 56 | After applying this, previous program will print:: 57 | 58 | 'la-la-la\nlimona, banana\n' 59 | 'This is string' 60 | 61 | To get this result, previous programs could be rewritten for 62 | current Python as (note, this gives the same result with new 63 | strings meaning):: 64 | 65 | def f(): 66 | """\ 67 | la-la-la 68 | limona, banana 69 | """ 70 | 71 | def g(): 72 | "This is \ 73 | string" 74 | 75 | Or stripping can be done with library routines at runtime (as 76 | pydoc does), but this decreases program readability. 77 | 78 | 79 | Implementation 80 | ============== 81 | 82 | I'll say nothing about CPython, Jython or Python.NET. 83 | 84 | In original Python, there is no info about the current indentation 85 | (in spaces) at compile time, so space and tab stripping should be 86 | done at parse time. Currently no flags can be passed to the 87 | parser in program text (like ``from __future__ import xxx``). I 88 | suggest enabling or disabling of this feature at Python compile 89 | time depending of CPP flag ``Py_PARSE_MULTILINE_STRINGS``. 90 | 91 | 92 | Alternatives 93 | ============ 94 | 95 | New interpretation of string constants can be implemented with flags 96 | 'i' and 'o' to string constants, like:: 97 | 98 | i""" 99 | SELECT * FROM car 100 | WHERE model = 'i525' 101 | """ is in new style, 102 | 103 | o"""SELECT * FROM employee 104 | WHERE birth < 1982 105 | """ is in old style, and 106 | 107 | """ 108 | SELECT employee.name, car.name, car.price FROM employee, car 109 | WHERE employee.salary * 36 > car.price 110 | """ is in new style after Python-x.y.z and in old style otherwise. 111 | 112 | Also this feature can be disabled if string is raw, i.e. if flag 'r' 113 | specified. 114 | 115 | 116 | Copyright 117 | ========= 118 | 119 | This document has been placed in the Public Domain. 120 | -------------------------------------------------------------------------------- /peps/pep-0299.rst: -------------------------------------------------------------------------------- 1 | PEP: 299 2 | Title: Special __main__() function in modules 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Jeff Epler 6 | Status: Rejected 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 12-Aug-2002 10 | Python-Version: 2.3 11 | Post-History: 29-Mar-2006 12 | 13 | 14 | 15 | Abstract 16 | ======== 17 | 18 | Many Python modules are also intended to be callable as standalone 19 | scripts. This PEP proposes that a special function called ``__main__()`` 20 | should serve this purpose. 21 | 22 | 23 | Motivation 24 | ========== 25 | 26 | There should be one simple and universal idiom for invoking a module 27 | as a standalone script. 28 | 29 | The semi-standard idiom:: 30 | 31 | if __name__ == '__main__': 32 | perform "standalone" functionality 33 | 34 | is unclear to programmers of languages like C and C++. It also does 35 | not permit invocation of the standalone function when the module is 36 | imported. The variant:: 37 | 38 | if __name__ == '__main__': 39 | main_function() 40 | 41 | is sometimes seen, but there exists no standard name for the function, 42 | and because arguments are taken from sys.argv it is not possible to 43 | pass specific arguments without changing the argument list seen by all 44 | other modules. (Imagine a threaded Python program, with two threads 45 | wishing to invoke the standalone functionality of different modules 46 | with different argument lists) 47 | 48 | 49 | Proposal 50 | ======== 51 | 52 | The standard name of the 'main function' should be ``__main__``. When a 53 | module is invoked on the command line, such as:: 54 | 55 | python mymodule.py 56 | 57 | then the module behaves as though the following lines existed at the 58 | end of the module (except that the attribute __sys may not be used or 59 | assumed to exist elsewhere in the script):: 60 | 61 | if globals().has_key("__main__"): 62 | import sys as __sys 63 | __sys.exit(__main__(__sys.argv)) 64 | 65 | Other modules may execute:: 66 | 67 | import mymodule mymodule.__main__(['mymodule', ...]) 68 | 69 | It is up to ``mymodule`` to document thread-safety issues or other 70 | issues which might restrict use of ``__main__``. (Other issues might 71 | include use of mutually exclusive GUI modules, non-sharable resources 72 | like hardware devices, reassignment of ``sys.stdin``/``stdout``, etc) 73 | 74 | 75 | Implementation 76 | ============== 77 | 78 | In ``modules/main.c``, the block near line 385 (after the 79 | ``PyRun_AnyFileExFlags`` call) will be changed so that the above code 80 | (or its C equivalent) is executed. 81 | 82 | 83 | Open Issues 84 | =========== 85 | 86 | * Should the return value from ``__main__`` be treated as the exit value? 87 | 88 | Yes. Many ``__main__`` will naturally return ``None``, which 89 | ``sys.exit`` translates into a "success" return code. In those that 90 | return a numeric result, it behaves just like the argument to 91 | ``sys.exit()`` or the return value from C's main(). 92 | 93 | * Should the argument list to ``__main__`` include ``argv[0]``, or just the 94 | "real" arguments ``argv[1:]``? 95 | 96 | ``argv[0]`` is included for symmetry with ``sys.argv`` and easy 97 | transition to the new standard idiom. 98 | 99 | 100 | Rejection 101 | ========= 102 | 103 | In a short discussion on python-dev [1]_, two major backwards 104 | compatibility problems were brought up and Guido pronounced that he 105 | doesn't like the idea anyway as it's "not worth the change (in docs, 106 | user habits, etc.) and there's nothing particularly broken." 107 | 108 | 109 | References 110 | ========== 111 | 112 | .. [1] Georg Brandl, "What about PEP 299", 113 | https://mail.python.org/pipermail/python-dev/2006-March/062951.html 114 | 115 | 116 | Copyright 117 | ========= 118 | 119 | This document has been placed in the public domain. 120 | -------------------------------------------------------------------------------- /peps/pep-0306.rst: -------------------------------------------------------------------------------- 1 | PEP: 306 2 | Title: How to Change Python's Grammar 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Michael Hudson , Jack Diederich , Alyssa Coghlan , Benjamin Peterson 6 | Status: Withdrawn 7 | Type: Informational 8 | Content-Type: text/x-rst 9 | Created: 29-Jan-2003 10 | Post-History: 30-Jan-2003 11 | 12 | 13 | Note 14 | ==== 15 | 16 | This PEP has been moved to the Python dev guide [1]_. 17 | 18 | 19 | Abstract 20 | ======== 21 | 22 | There's more to changing Python's grammar than editing 23 | ``Grammar/Grammar`` and ``Python/compile.c``. This PEP aims to be a 24 | checklist of places that must also be fixed. 25 | 26 | It is probably incomplete. If you see omissions, just add them if 27 | you can -- you are not going to offend the author's sense of 28 | ownership. Otherwise submit a bug or patch and assign it to mwh. 29 | 30 | This PEP is not intended to be an instruction manual on Python 31 | grammar hacking, for several reasons. 32 | 33 | 34 | Rationale 35 | ========= 36 | 37 | People are getting this wrong all the time; it took well over a 38 | year before someone noticed [2]_ that adding the floor division 39 | operator (``//``) broke the ``parser`` module. 40 | 41 | 42 | Checklist 43 | ========= 44 | 45 | - ``Grammar/Grammar``: OK, you'd probably worked this one out :) 46 | 47 | - ``Parser/Python.asdl`` may need changes to match the ``Grammar``. Run 48 | ``make`` to regenerate ``Include/Python-ast.h`` and 49 | ``Python/Python-ast.c``. 50 | 51 | - ``Python/ast.c`` will need changes to create the AST objects 52 | involved with the ``Grammar`` change. ``Lib/compiler/ast.py`` will 53 | need matching changes to the pure-python AST objects. 54 | 55 | - ``Parser/pgen`` needs to be rerun to regenerate ``Include/graminit.h`` 56 | and ``Python/graminit.c``. (make should handle this for you.) 57 | 58 | - ``Python/symbtable.c``: This handles the symbol collection pass 59 | that happens immediately before the compilation pass. 60 | 61 | - ``Python/compile.c``: You will need to create or modify the 62 | ``compiler_*`` functions to generate opcodes for your productions. 63 | 64 | - You may need to regenerate ``Lib/symbol.py`` and/or ``Lib/token.py`` 65 | and/or ``Lib/keyword.py``. 66 | 67 | - The ``parser`` module. Add some of your new syntax to ``test_parser``, 68 | bang on ``Modules/parsermodule.c`` until it passes. 69 | 70 | - Add some usage of your new syntax to ``test_grammar.py``. 71 | 72 | - The ``compiler`` package. A good test is to compile the standard 73 | library and test suite with the ``compiler`` package and then check 74 | it runs. Note that this only needs to be done in Python 2.x. 75 | 76 | - If you've gone so far as to change the token structure of 77 | Python, then the ``Lib/tokenizer.py`` library module will need to 78 | be changed. 79 | 80 | - Certain changes may require tweaks to the library module 81 | ``pyclbr``. 82 | 83 | - Documentation must be written! 84 | 85 | - After everything's been checked in, you're likely to see a new 86 | change to ``Python/Python-ast.c``. This is because this 87 | (generated) file contains the SVN version of the source from 88 | which it was generated. There's no way to avoid this; you just 89 | have to submit this file separately. 90 | 91 | 92 | References 93 | ========== 94 | 95 | .. [1] CPython Developer's Guide: Changing CPython's Grammar 96 | https://devguide.python.org/grammar/ 97 | 98 | .. [2] SF Bug #676521, parser module validation failure 99 | https://bugs.python.org/issue676521 100 | 101 | 102 | Copyright 103 | ========= 104 | 105 | This document has been placed in the public domain. 106 | 107 | 108 | 109 | .. 110 | Local Variables: 111 | mode: indented-text 112 | indent-tabs-mode: nil 113 | sentence-end-double-space: t 114 | fill-column: 70 115 | End: 116 | -------------------------------------------------------------------------------- /peps/pep-0332.rst: -------------------------------------------------------------------------------- 1 | PEP: 332 2 | Title: Byte vectors and String/Unicode Unification 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Skip Montanaro 6 | Status: Rejected 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 11-Aug-2004 10 | Python-Version: 2.5 11 | Post-History: 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | This PEP outlines the introduction of a raw ``bytes`` sequence object 18 | and the unification of the current ``str`` and ``unicode`` objects. 19 | 20 | 21 | Rejection Notice 22 | ================ 23 | 24 | This PEP is rejected in this form. The author has expressed lack of 25 | time to continue to shepherd it, and discussion on python-dev has 26 | moved to a slightly different proposal which will (eventually) be 27 | written up as a new PEP. See the thread starting at 28 | https://mail.python.org/pipermail/python-dev/2006-February/060930.html. 29 | 30 | 31 | Rationale 32 | ========= 33 | 34 | Python's current string objects are overloaded. They serve both to 35 | hold ASCII and non-ASCII character data and to also hold sequences of 36 | raw bytes which have no reasonable interpretation as displayable 37 | character sequences. This overlap hasn't been a big problem in the 38 | past, but as Python moves closer to requiring source code to be 39 | properly encoded, the use of strings to represent raw byte sequences 40 | will be more problematic. In addition, as Python's Unicode support 41 | has improved, it's easier to consider strings as ASCII-encoded Unicode 42 | objects. 43 | 44 | 45 | Proposed Implementation 46 | ======================= 47 | 48 | The number in parentheses indicates the Python version in which the 49 | feature will be introduced. 50 | 51 | - Add a ``bytes`` builtin which is just a synonym for ``str``. (2.5) 52 | 53 | - Add a ``b"..."`` string literal which is equivalent to raw string 54 | literals, with the exception that values which conflict with the 55 | source encoding of the containing file not generate warnings. (2.5) 56 | 57 | - Warn about the use of variables named "bytes". (2.5 or 2.6) 58 | 59 | - Introduce a ``bytes`` builtin which refers to a sequence distinct 60 | from the ``str`` type. (2.6) 61 | 62 | - Make ``str`` a synonym for ``unicode``. (3.0) 63 | 64 | 65 | Bytes Object API 66 | ================ 67 | 68 | TBD. 69 | 70 | 71 | Issues 72 | ====== 73 | 74 | - Can this be accomplished before Python 3.0? 75 | 76 | - Should ``bytes`` objects be mutable or immutable? (Guido seems to 77 | like them to be mutable.) 78 | 79 | 80 | Copyright 81 | ========= 82 | 83 | This document has been placed in the public domain. 84 | 85 | 86 | 87 | .. 88 | Local Variables: 89 | mode: indented-text 90 | indent-tabs-mode: nil 91 | sentence-end-double-space: t 92 | fill-column: 70 93 | End: 94 | -------------------------------------------------------------------------------- /peps/pep-0336.rst: -------------------------------------------------------------------------------- 1 | PEP: 336 2 | Title: Make None Callable 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Andrew McClelland 6 | Status: Rejected 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 28-Oct-2004 10 | Post-History: 11 | 12 | 13 | Abstract 14 | ======== 15 | 16 | ``None`` should be a callable object that when called with any 17 | arguments has no side effect and returns ``None``. 18 | 19 | 20 | BDFL Pronouncement 21 | ================== 22 | 23 | This PEP is rejected. It is considered a feature that ``None`` raises 24 | an error when called. The proposal falls short in tests for 25 | obviousness, clarity, explicitness, and necessity. The provided Switch 26 | example is nice but easily handled by a simple lambda definition. 27 | See python-dev discussion on 17 June 2005 [1]_. 28 | 29 | 30 | Motivation 31 | ========== 32 | 33 | To allow a programming style for selectable actions that is more 34 | in accordance with the minimalistic functional programming goals 35 | of the Python language. 36 | 37 | 38 | Rationale 39 | ========= 40 | 41 | Allow the use of ``None`` in method tables as a universal no effect 42 | rather than either (1) checking a method table entry against ``None`` 43 | before calling, or (2) writing a local no effect method with 44 | arguments similar to other functions in the table. 45 | 46 | The semantics would be effectively:: 47 | 48 | class None: 49 | 50 | def __call__(self, *args): 51 | pass 52 | 53 | 54 | How To Use 55 | ========== 56 | 57 | Before, checking function table entry against ``None``:: 58 | 59 | class Select: 60 | 61 | def a(self, input): 62 | print 'a' 63 | 64 | def b(self, input): 65 | print 'b' 66 | 67 | def c(self, input): 68 | print 'c' 69 | 70 | def __call__(self, input): 71 | function = { 1 : self.a, 72 | 2 : self.b, 73 | 3 : self.c 74 | }.get(input, None) 75 | if function: return function(input) 76 | 77 | Before, using a local no effect method:: 78 | 79 | class Select: 80 | 81 | def a(self, input): 82 | print 'a' 83 | 84 | def b(self, input): 85 | print 'b' 86 | 87 | def c(self, input): 88 | print 'c' 89 | 90 | def nop(self, input): 91 | pass 92 | 93 | def __call__(self, input): 94 | return { 1 : self.a, 95 | 2 : self.b, 96 | 3 : self.c 97 | }.get(input, self.nop)(input) 98 | 99 | After:: 100 | 101 | class Select: 102 | 103 | def a(self, input): 104 | print 'a' 105 | 106 | def b(self, input): 107 | print 'b' 108 | 109 | def c(self, input): 110 | print 'c' 111 | 112 | def __call__(self, input): 113 | return { 1 : self.a, 114 | 2 : self.b, 115 | 3 : self.c 116 | }.get(input, None)(input) 117 | 118 | 119 | References 120 | ========== 121 | 122 | .. [1] Raymond Hettinger, Propose to reject PEP 336 -- Make None Callable 123 | https://mail.python.org/pipermail/python-dev/2005-June/054280.html 124 | 125 | 126 | Copyright 127 | ========= 128 | 129 | This document has been placed in the public domain. 130 | -------------------------------------------------------------------------------- /peps/pep-0341.rst: -------------------------------------------------------------------------------- 1 | PEP: 341 2 | Title: Unifying try-except and try-finally 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Georg Brandl 6 | Status: Final 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 04-May-2005 10 | Python-Version: 2.5 11 | Post-History: 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | This PEP proposes a change in the syntax and semantics of try 18 | statements to allow combined try-except-finally blocks. This 19 | means in short that it would be valid to write:: 20 | 21 | try: 22 | 23 | except Exception: 24 | 25 | finally: 26 | 27 | 28 | 29 | Rationale/Proposal 30 | ================== 31 | 32 | There are many use cases for the try-except statement and 33 | for the try-finally statement per se; however, often one needs 34 | to catch exceptions and execute some cleanup code afterwards. 35 | It is slightly annoying and not very intelligible that 36 | one has to write:: 37 | 38 | f = None 39 | try: 40 | try: 41 | f = open(filename) 42 | text = f.read() 43 | except IOError: 44 | print 'An error occurred' 45 | finally: 46 | if f: 47 | f.close() 48 | 49 | So it is proposed that a construction like this:: 50 | 51 | try: 52 | 53 | except Ex1: 54 | 55 | 56 | else: 57 | 58 | finally: 59 | 60 | 61 | be exactly the same as the legacy:: 62 | 63 | try: 64 | try: 65 | 66 | except Ex1: 67 | 68 | 69 | else: 70 | 71 | finally: 72 | 73 | 74 | This is backwards compatible, and every try statement that is 75 | legal today would continue to work. 76 | 77 | 78 | Changes to the grammar 79 | ====================== 80 | 81 | The grammar for the try statement, which is currently:: 82 | 83 | try_stmt: ('try' ':' suite (except_clause ':' suite)+ 84 | ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) 85 | 86 | would have to become:: 87 | 88 | try_stmt: 'try' ':' suite 89 | ( 90 | (except_clause ':' suite)+ 91 | ['else' ':' suite] 92 | ['finally' ':' suite] 93 | | 94 | 'finally' ':' suite 95 | ) 96 | 97 | 98 | Implementation 99 | ============== 100 | 101 | As the PEP author currently does not have sufficient knowledge 102 | of the CPython implementation, he is unfortunately not able 103 | to deliver one. Thomas Lee has submitted a patch [2]_. 104 | 105 | However, according to Guido, it should be a piece of cake to 106 | implement [1]_ -- at least for a core hacker. 107 | 108 | This patch was committed 17 December 2005, SVN revision 41740 [3]_. 109 | 110 | 111 | References 112 | ========== 113 | 114 | .. [1] https://mail.python.org/pipermail/python-dev/2005-May/053319.html 115 | .. [2] https://bugs.python.org/issue1355913 116 | .. [3] https://mail.python.org/pipermail/python-checkins/2005-December/048457.html 117 | 118 | 119 | Copyright 120 | ========= 121 | 122 | This document has been placed in the public domain. 123 | 124 | 125 | 126 | .. 127 | Local Variables: 128 | mode: indented-text 129 | indent-tabs-mode: nil 130 | sentence-end-double-space: t 131 | fill-column: 70 132 | End: 133 | -------------------------------------------------------------------------------- /peps/pep-0375.rst: -------------------------------------------------------------------------------- 1 | PEP: 375 2 | Title: Python 3.1 Release Schedule 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Benjamin Peterson 6 | Status: Final 7 | Type: Informational 8 | Topic: Release 9 | Content-Type: text/x-rst 10 | Created: 08-Feb-2009 11 | Python-Version: 3.1 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | This document describes the development and release schedule for Python 3.1. 18 | The schedule primarily concerns itself with PEP-sized items. Small features may 19 | be added up to and including the first beta release. Bugs may be fixed until 20 | the final release. 21 | 22 | 23 | Release Manager and Crew 24 | ======================== 25 | 26 | =================== ================== 27 | Position Name 28 | =================== ================== 29 | 3.1 Release Manager Benjamin Peterson 30 | Windows installers Martin v. Loewis 31 | Mac installers Ronald Oussoren 32 | =================== ================== 33 | 34 | 35 | Release Schedule 36 | ================ 37 | 38 | - 3.1a1 March 7, 2009 39 | - 3.1a2 April 4, 2009 40 | - 3.1b1 May 6, 2009 41 | - 3.1rc1 May 30, 2009 42 | - 3.1rc2 June 13, 2009 43 | - 3.1 final June 27, 2009 44 | 45 | Maintenance Releases 46 | ==================== 47 | 48 | 3.1 is no longer maintained. 3.1 received security fixes until June 49 | 2012. 50 | 51 | Previous maintenance releases are: 52 | 53 | - v3.1.1rc1 2009-08-13 54 | - v3.1.1 2009-08-16 55 | - v3.1.2rc1 2010-03-06 56 | - v3.1.2 2010-03-20 57 | - v3.1.3rc1 2010-11-13 58 | - v3.1.3 2010-11-27 59 | - v3.1.4rc1 2011-05-29 60 | - v3.1.4 2011-06-11 61 | - v3.1.5rc1 2012-02-23 62 | - v3.1.5rc2 2012-03-15 63 | - v3.1.5 2012-04-06 64 | 65 | Features for 3.1 66 | ================ 67 | 68 | - importlib 69 | - io in C 70 | - Update simplejson to the latest external version [#simplejson]_. 71 | - Ordered dictionary for collections (:pep:`372`). 72 | - auto-numbered replacement fields in str.format() strings [#strformat]_ 73 | - Nested with-statements in one with statement 74 | 75 | 76 | Footnotes 77 | ========= 78 | 79 | .. [#simplejson] 80 | http://bugs.python.org/issue4136 81 | 82 | .. [#strformat] 83 | http://bugs.python.org/issue5237 84 | 85 | 86 | 87 | Copyright 88 | ========= 89 | 90 | This document has been placed in the public domain. 91 | 92 | 93 | 94 | .. 95 | Local Variables: 96 | mode: indented-text 97 | indent-tabs-mode: nil 98 | sentence-end-double-space: t 99 | fill-column: 70 100 | coding: utf-8 101 | End: 102 | -------------------------------------------------------------------------------- /peps/pep-0392.rst: -------------------------------------------------------------------------------- 1 | PEP: 392 2 | Title: Python 3.2 Release Schedule 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Georg Brandl 6 | Status: Final 7 | Type: Informational 8 | Topic: Release 9 | Content-Type: text/x-rst 10 | Created: 30-Dec-2009 11 | Python-Version: 3.2 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | This document describes the development and release schedule for the 18 | Python 3.2 series. The schedule primarily concerns itself with PEP-sized 19 | items. 20 | 21 | .. Small features may be added up to and including the first beta 22 | release. Bugs may be fixed until the final release, which is planned 23 | for February 2011. 24 | 25 | 26 | Release Manager and Crew 27 | ======================== 28 | 29 | - 3.2 Release Manager: Georg Brandl 30 | - Windows installers: Martin v. Loewis 31 | - Mac installers: Ronald Oussoren 32 | - Documentation: Georg Brandl 33 | 34 | 35 | 3.2 Lifespan 36 | ============ 37 | 38 | 3.2 will receive bugfix updates approximately every 4-6 months for 39 | approximately 18 months. After the release of 3.3.0 final (see PEP 40 | 398), a final 3.2 bugfix update will be released. After that, 41 | security updates (source only) will be released until 5 years after 42 | the release of 3.2 final, which was planned for February 2016. 43 | 44 | As of 2016-02-20, Python 3.2.x reached end-of-life status. The final 45 | source release was 3.2.6 in October 2014. 46 | 47 | 48 | Release Schedule 49 | ================ 50 | 51 | 3.2 schedule 52 | ------------ 53 | 54 | - 3.2 alpha 1: August 1, 2010 55 | - 3.2 alpha 2: September 6, 2010 56 | - 3.2 alpha 3: October 12, 2010 57 | - 3.2 alpha 4: November 16, 2010 58 | - 3.2 beta 1: December 6, 2010 59 | 60 | (No new features beyond this point.) 61 | 62 | - 3.2 beta 2: December 20, 2010 63 | - 3.2 candidate 1: January 16, 2011 64 | - 3.2 candidate 2: January 31, 2011 65 | - 3.2 candidate 3: February 14, 2011 66 | - 3.2 final: February 20, 2011 67 | 68 | .. don't forget to update final date above as well 69 | 70 | 3.2.1 schedule 71 | -------------- 72 | 73 | - 3.2.1 beta 1: May 8, 2011 74 | - 3.2.1 candidate 1: May 17, 2011 75 | - 3.2.1 candidate 2: July 3, 2011 76 | - 3.2.1 final: July 11, 2011 77 | 78 | 3.2.2 schedule 79 | -------------- 80 | 81 | - 3.2.2 candidate 1: August 14, 2011 82 | - 3.2.2 final: September 4, 2011 83 | 84 | 3.2.3 schedule 85 | -------------- 86 | 87 | - 3.2.3 candidate 1: February 25, 2012 88 | - 3.2.3 candidate 2: March 18, 2012 89 | - 3.2.3 final: April 11, 2012 90 | 91 | 3.2.4 schedule 92 | -------------- 93 | 94 | - 3.2.4 candidate 1: March 23, 2013 95 | - 3.2.4 final: April 6, 2013 96 | 97 | 3.2.5 schedule (regression fix release) 98 | --------------------------------------- 99 | 100 | - 3.2.5 final: May 13, 2013 101 | 102 | -- Only security releases after 3.2.5 -- 103 | 104 | 3.2.6 schedule 105 | -------------- 106 | 107 | - 3.2.6 candidate 1 (source-only release): October 4, 2014 108 | - 3.2.6 final (source-only release): October 11, 2014 109 | 110 | 111 | Features for 3.2 112 | ================ 113 | 114 | Note that :pep:`3003` is in effect: no changes to language 115 | syntax and no additions to the builtins may be made. 116 | 117 | No large-scale changes have been recorded yet. 118 | 119 | 120 | Copyright 121 | ========= 122 | 123 | This document has been placed in the public domain. 124 | 125 | 126 | 127 | .. 128 | Local Variables: 129 | mode: indented-text 130 | indent-tabs-mode: nil 131 | sentence-end-double-space: t 132 | fill-column: 70 133 | coding: utf-8 134 | End: 135 | -------------------------------------------------------------------------------- /peps/pep-0415.rst: -------------------------------------------------------------------------------- 1 | PEP: 415 2 | Title: Implement context suppression with exception attributes 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Benjamin Peterson 6 | BDFL-Delegate: Alyssa Coghlan 7 | Status: Final 8 | Type: Standards Track 9 | Content-Type: text/x-rst 10 | Created: 26-Feb-2012 11 | Python-Version: 3.3 12 | Post-History: 26-Feb-2012 13 | Replaces: 409 14 | Resolution: https://mail.python.org/pipermail/python-dev/2012-May/119467.html 15 | 16 | 17 | Abstract 18 | ======== 19 | 20 | :pep:`409` introduced support for the ``raise exc from None`` construct to 21 | allow the display of the exception context to be explicitly suppressed. 22 | This PEP retains the language level changes already implemented in :pep:`409`, 23 | but replaces the underlying implementation mechanism with a simpler approach 24 | based on a new ``__suppress_context__`` attribute on all ``BaseException`` 25 | instances. 26 | 27 | 28 | PEP Acceptance 29 | ============== 30 | 31 | This PEP was accepted by Alyssa Coghlan on the 14th of May, 2012. 32 | 33 | 34 | Rationale 35 | ========= 36 | 37 | :pep:`409` changes ``__cause__`` to be ``Ellipsis`` by default. Then if 38 | ``__cause__`` is set to ``None`` by ``raise exc from None``, no context or cause 39 | will be printed should the exception be uncaught. 40 | 41 | The main problem with this scheme is it complicates the role of 42 | ``__cause__``. ``__cause__`` should indicate the cause of the exception not 43 | whether ``__context__`` should be printed or not. This use of ``__cause__`` is 44 | also not easily extended in the future. For example, we may someday want to 45 | allow the programmer to select which of ``__context__`` and ``__cause__`` will 46 | be printed. The :pep:`409` implementation is not amenable to this. 47 | 48 | The use of ``Ellipsis`` is a hack. Before :pep:`409`, ``Ellipsis`` was used 49 | exclusively in extended slicing. Extended slicing has nothing to do with 50 | exceptions, so it's not clear to someone inspecting an exception object why 51 | ``__cause__`` should be set to ``Ellipsis``. Using ``Ellipsis`` by default for 52 | ``__cause__`` makes it asymmetrical with ``__context__``. 53 | 54 | 55 | Proposal 56 | ======== 57 | 58 | A new attribute on ``BaseException``, ``__suppress_context__``, will 59 | be introduced. Whenever ``__cause__`` is set, ``__suppress_context__`` 60 | will be set to ``True``. In particular, ``raise exc from cause`` 61 | syntax will set ``exc.__suppress_context__`` to ``True``. Exception 62 | printing code will check for that attribute to determine whether 63 | context and cause will be printed. ``__cause__`` will return to its 64 | original purpose and values. 65 | 66 | There is precedence for ``__suppress_context__`` with the 67 | ``print_line_and_file`` exception attribute. 68 | 69 | To summarize, ``raise exc from cause`` will be equivalent to:: 70 | 71 | exc.__cause__ = cause 72 | raise exc 73 | 74 | where ``exc.__cause__ = cause`` implicitly sets 75 | ``exc.__suppress_context__``. 76 | 77 | 78 | Patches 79 | ======= 80 | 81 | There is a patch on `Issue 14133`_. 82 | 83 | 84 | References 85 | ========== 86 | 87 | .. _issue 14133: 88 | http://bugs.python.org/issue14133 89 | 90 | 91 | Copyright 92 | ========= 93 | 94 | This document has been placed in the public domain. 95 | 96 | 97 | .. 98 | Local Variables: 99 | mode: indented-text 100 | indent-tabs-mode: nil 101 | sentence-end-double-space: t 102 | fill-column: 70 103 | coding: utf-8 104 | End: 105 | -------------------------------------------------------------------------------- /peps/pep-0417.rst: -------------------------------------------------------------------------------- 1 | PEP: 417 2 | Title: Including mock in the Standard Library 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Michael Foord 6 | Status: Final 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 12-Mar-2012 10 | Python-Version: 3.3 11 | Post-History: 12-Mar-2012 12 | Resolution: https://mail.python.org/pipermail/python-dev/2012-March/117507.html 13 | 14 | 15 | Abstract 16 | ======== 17 | 18 | This PEP proposes adding the mock [1]_ testing library 19 | to the Python standard library as ``unittest.mock``. 20 | 21 | 22 | Rationale 23 | ========= 24 | 25 | Creating mock objects for testing is a common need in Python. 26 | Many developers create ad-hoc mocks, as needed, in their test 27 | suites. This is currently what we do in the Python test suite, 28 | where a standardised mock object library would be helpful. 29 | 30 | There are many mock object libraries available for Python [2]_. 31 | Of these, mock is overwhelmingly the most popular, with as many 32 | downloads on PyPI as the other mocking libraries combined. 33 | 34 | An advantage of mock is that it is a mocking library and not a 35 | framework. It provides a configurable and flexible mock object, 36 | without being opinionated about how you write your tests. The 37 | mock api is now well battle-tested and stable. 38 | 39 | mock also handles safely monkeypatching and unmonkeypatching 40 | objects during the scope of a test. This is hard to do safely 41 | and many developers / projects mimic this functionality 42 | (often incorrectly). A standardised way to do this, handling 43 | the complexity of patching in the presence of the descriptor 44 | protocol (etc) is useful. People are asking for a "patch" [3]_ 45 | feature to unittest. Doing this via mock.patch is preferable 46 | to re-implementing part of this functionality in unittest. 47 | 48 | 49 | Background 50 | ========== 51 | 52 | Addition of mock to the Python standard library was discussed 53 | and agreed to at the Python Language Summit 2012. 54 | 55 | 56 | Open Issues 57 | =========== 58 | 59 | As of release 0.8, which is current at the time of writing, 60 | mock is compatible with Python 2.4-3.2. Moving into the Python 61 | standard library will allow for the removal of some Python 2 62 | specific "compatibility hacks". 63 | 64 | mock 0.8 introduced a new feature, "auto-speccing", obsoletes 65 | an older mock feature called "mocksignature". The 66 | "mocksignature" functionality can be removed from mock 67 | altogether prior to inclusion. 68 | 69 | 70 | References 71 | ========== 72 | 73 | .. [1] `mock library on PyPI `_ 74 | .. [2] http://pypi.python.org/pypi?%3Aaction=search&term=mock&submit=search 75 | .. [3] http://bugs.python.org/issue11664 76 | 77 | 78 | Copyright 79 | ========= 80 | 81 | This document has been placed in the public domain. 82 | 83 | 84 | 85 | .. 86 | Local Variables: 87 | mode: indented-text 88 | indent-tabs-mode: nil 89 | sentence-end-double-space: t 90 | fill-column: 70 91 | coding: utf-8 92 | End: 93 | -------------------------------------------------------------------------------- /peps/pep-0418/clock_resolution.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | try: 4 | from time import timeout_time 5 | except ImportError: 6 | from time import time as timeout_time 7 | 8 | def compute_resolution(func): 9 | resolution = None 10 | points = 0 11 | timeout = timeout_time() + 1.0 12 | previous = func() 13 | while timeout_time() < timeout or points < 3: 14 | for loop in range(10): 15 | t1 = func() 16 | t2 = func() 17 | dt = t2 - t1 18 | if 0 < dt: 19 | break 20 | else: 21 | dt = t2 - previous 22 | if dt <= 0.0: 23 | continue 24 | if resolution is not None: 25 | resolution = min(resolution, dt) 26 | else: 27 | resolution = dt 28 | points += 1 29 | previous = func() 30 | return resolution 31 | 32 | def format_duration(dt): 33 | if dt >= 1e-3: 34 | return "%.0f ms" % (dt * 1e3) 35 | if dt >= 1e-6: 36 | return "%.0f us" % (dt * 1e6) 37 | else: 38 | return "%.0f ns" % (dt * 1e9) 39 | 40 | def test_clock(name, func): 41 | print("%s:" % name) 42 | resolution = compute_resolution(func) 43 | print("- resolution in Python: %s" % format_duration(resolution)) 44 | 45 | 46 | clocks = ['clock', 'perf_counter', 'process_time'] 47 | if hasattr(time, 'monotonic'): 48 | clocks.append('monotonic') 49 | clocks.append('time') 50 | for name in clocks: 51 | func = getattr(time, name) 52 | test_clock("%s()" % name, func) 53 | info = time.get_clock_info(name) 54 | print("- implementation: %s" % info.implementation) 55 | print("- resolution: %s" % format_duration(info.resolution)) 56 | 57 | clock_ids = [name for name in dir(time) if name.startswith("CLOCK_")] 58 | clock_ids.sort() 59 | for clock_id_text in clock_ids: 60 | clock_id = getattr(time, clock_id_text) 61 | name = 'clock_gettime(%s)' % clock_id_text 62 | def gettime(): 63 | return time.clock_gettime(clock_id) 64 | try: 65 | gettime() 66 | except OSError as err: 67 | print("%s failed: %s" % (name, err)) 68 | continue 69 | test_clock(name, gettime) 70 | resolution = time.clock_getres(clock_id) 71 | print("- announced resolution: %s" % format_duration(resolution)) 72 | 73 | -------------------------------------------------------------------------------- /peps/pep-0424.rst: -------------------------------------------------------------------------------- 1 | PEP: 424 2 | Title: A method for exposing a length hint 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Alex Gaynor 6 | Status: Final 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 14-Jul-2012 10 | Python-Version: 3.4 11 | Post-History: `15-Jul-2012 `__ 12 | 13 | Abstract 14 | ======== 15 | 16 | CPython currently defines a ``__length_hint__`` method on several 17 | types, such as various iterators. This method is then used by various 18 | other functions (such as ``list``) to presize lists based on the 19 | estimate returned by ``__length_hint__``. Types which are not sized, 20 | and thus should not define ``__len__``, can then define 21 | ``__length_hint__``, to allow estimating or computing a size (such as 22 | many iterators). 23 | 24 | Specification 25 | ============= 26 | 27 | This PEP formally documents ``__length_hint__`` for other interpreters 28 | and non-standard-library Python modules to implement. 29 | 30 | ``__length_hint__`` must return an integer (else a ``TypeError`` is 31 | raised) or ``NotImplemented``, and is not required to be accurate. It 32 | may return a value that is either larger or smaller than the actual 33 | size of the container. A return value of ``NotImplemented`` indicates 34 | that there is no finite length estimate. It may not return a negative 35 | value (else a ValueError is raised). 36 | 37 | In addition, a new function ``operator.length_hint`` hint is added, 38 | with the following semantics (which define how ``__length_hint__`` 39 | should be used):: 40 | 41 | def length_hint(obj, default=0): 42 | """Return an estimate of the number of items in obj. 43 | 44 | This is useful for presizing containers when building from an 45 | iterable. 46 | 47 | If the object supports len(), the result will be 48 | exact. Otherwise, it may over- or under-estimate by an 49 | arbitrary amount. The result will be an integer >= 0. 50 | """ 51 | try: 52 | return len(obj) 53 | except TypeError: 54 | try: 55 | get_hint = type(obj).__length_hint__ 56 | except AttributeError: 57 | return default 58 | try: 59 | hint = get_hint(obj) 60 | except TypeError: 61 | return default 62 | if hint is NotImplemented: 63 | return default 64 | if not isinstance(hint, int): 65 | raise TypeError("Length hint must be an integer, not %r" % 66 | type(hint)) 67 | if hint < 0: 68 | raise ValueError("__length_hint__() should return >= 0") 69 | return hint 70 | 71 | 72 | Rationale 73 | ========= 74 | 75 | Being able to pre-allocate lists based on the expected size, as 76 | estimated by ``__length_hint__``, can be a significant optimization. 77 | CPython has been observed to run some code faster than PyPy, purely 78 | because of this optimization being present. 79 | 80 | Copyright 81 | ========= 82 | 83 | This document has been placed into the public domain. 84 | 85 | 86 | 87 | .. 88 | Local Variables: 89 | mode: indented-text 90 | indent-tabs-mode: nil 91 | sentence-end-double-space: t 92 | fill-column: 70 93 | coding: utf-8 94 | End: 95 | -------------------------------------------------------------------------------- /peps/pep-0433/bench_cloexec.py: -------------------------------------------------------------------------------- 1 | """ 2 | Linux 3.6, O_CLOEXEC: 3 | 4 | open(cloexec=False) + close(): 7.76 us per call 5 | open(cloexec=True) + close(): 7.87 us per call 6 | 7 | => 1% slower 8 | 9 | Linux 3.6, ioctl(FIOCLEX): 10 | 11 | open(cloexec=False) + close(): 7.77 us per call 12 | open(cloexec=True) + close(): 8.02 us per call 13 | 14 | => 3% slower 15 | 16 | Linux 3.6, fnctl(F_GETFD) + fnctl(F_SETFD): 17 | 18 | open(cloexec=False) + close(): 7.77 us per call 19 | open(cloexec=True) + close(): 8.01 us per call 20 | 21 | => 3% slower 22 | """ 23 | import os, time 24 | 25 | name = __file__ 26 | LOOPS = 10**5 27 | RUNS = 5 28 | 29 | for cloexec in (False, True): 30 | best = None 31 | for run in range(RUNS): 32 | print("cloexec", cloexec, "run", run) 33 | time.sleep(1) 34 | start = time.perf_counter() 35 | for loops in range(LOOPS): 36 | fd = os.open(name, os.O_RDONLY, cloexec=cloexec) 37 | os.close(fd) 38 | dt = time.perf_counter() - start 39 | if best is not None: 40 | best = min(best, dt) 41 | else: 42 | best = dt 43 | 44 | seconds = best / LOOPS 45 | print("open(cloexec=%s) + close(): %.2f us per call" % (cloexec, seconds * 1e6)) 46 | -------------------------------------------------------------------------------- /peps/pep-0433/openbsd_bug.py: -------------------------------------------------------------------------------- 1 | # Script testing an OpenBSD bug 2 | # 3 | # The script fails with "OS BUG!!!" with OpenBSD older than 5.2. 4 | # It works on any version using USE_FORK = False. 5 | USE_FORK = True 6 | 7 | import fcntl, os, sys 8 | 9 | fd = os.open("/etc/passwd", os.O_RDONLY) 10 | flags = fcntl.fcntl(fd, fcntl.F_GETFD) 11 | flags |= fcntl.FD_CLOEXEC 12 | fcntl.fcntl(fd, fcntl.F_SETFD, flags) 13 | 14 | code = """ 15 | import os, sys 16 | fd = int(sys.argv[1]) 17 | try: 18 | os.fstat(fd) 19 | except OSError: 20 | print("fd %s closed by exec (FD_CLOEXEC works)" % fd) 21 | else: 22 | print("fd %s not closed by exec: FD_CLOEXEC doesn't work, OS BUG!!!" % fd) 23 | """ 24 | 25 | args = [sys.executable, '-c', code, str(fd)] 26 | if USE_FORK: 27 | pid = os.fork() 28 | if pid: 29 | os.waitpid(pid, 0) 30 | sys.exit(0) 31 | 32 | os.execv(args[0], args) 33 | -------------------------------------------------------------------------------- /peps/pep-0446/test_cloexec.py: -------------------------------------------------------------------------------- 1 | import os, fcntl, sys, errno 2 | 3 | def get_cloexec(fd): 4 | try: 5 | flags = fcntl.fcntl(fd, fcntl.F_GETFD) 6 | return bool(flags & fcntl.FD_CLOEXEC) 7 | except IOError as err: 8 | if err.errno == errno.EBADF: 9 | return '' 10 | else: 11 | return str(err) 12 | 13 | def set_cloexec(fd): 14 | flags = fcntl.fcntl(fd, fcntl.F_GETFD) 15 | flags |= fcntl.FD_CLOEXEC 16 | fcntl.fcntl(fd, fcntl.F_SETFD, flags) 17 | 18 | def main(): 19 | f = open(__file__, "rb") 20 | fd = f.fileno() 21 | print("initial state: fd=%s, cloexec=%s" % (fd, get_cloexec(fd))) 22 | 23 | 24 | pid = os.fork() 25 | if not pid: 26 | set_cloexec(fd) 27 | print("child process after fork, set cloexec: cloexec=%s" % get_cloexec(fd)) 28 | child_argv = [sys.executable, __file__, str(fd), 29 | 'child process after exec'] 30 | os.execv(child_argv[0], child_argv) 31 | 32 | os.waitpid(pid, 0) 33 | print("parent process after fork: cloexec=%s" % get_cloexec(fd)) 34 | child_argv = [sys.executable, __file__, str(fd), 35 | 'parent process after exec'] 36 | os.execv(child_argv[0], child_argv) 37 | 38 | def after_exec(): 39 | fd = int(sys.argv[1]) 40 | name = sys.argv[2] 41 | print("%s: fd=%s, cloexec=%s" 42 | % (name, fd, get_cloexec(fd))) 43 | sys.exit() 44 | 45 | if __name__ == "__main__": 46 | if len(sys.argv) == 1: 47 | main() 48 | else: 49 | after_exec() 50 | 51 | -------------------------------------------------------------------------------- /peps/pep-0458-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0458-1.png -------------------------------------------------------------------------------- /peps/pep-0464.rst: -------------------------------------------------------------------------------- 1 | PEP: 464 2 | Title: Removal of the PyPI Mirror Authenticity API 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Donald Stufft 6 | BDFL-Delegate: Richard Jones 7 | Discussions-To: distutils-sig@python.org 8 | Status: Final 9 | Type: Process 10 | Topic: Packaging 11 | Content-Type: text/x-rst 12 | Created: 02-Mar-2014 13 | Post-History: 04-Mar-2014 14 | Replaces: 381 15 | Resolution: https://mail.python.org/pipermail/distutils-sig/2014-March/024027.html 16 | 17 | 18 | Abstract 19 | ======== 20 | 21 | This PEP proposes the deprecation and removal of the PyPI Mirror Authenticity 22 | API, this includes the /serverkey URL and all of the URLs under /serversig. 23 | 24 | 25 | Rationale 26 | ========= 27 | 28 | The PyPI mirroring infrastructure (defined in :pep:`381`) provides a means to 29 | mirror the content of PyPI used by the automatic installers, and as a component 30 | of that, it provides a method for verifying the authenticity of the mirrored 31 | content. 32 | 33 | This PEP proposes the removal of this API due to: 34 | 35 | * There are no known implementations that utilize this API, this includes 36 | `pip `_ and 37 | `setuptools `_. 38 | * Because this API uses DSA it is vulnerable to leaking the private key if 39 | there is *any* bias in the random nonce. 40 | * This API solves one small corner of the trust problem, however the problem 41 | itself is much larger and it would be better to have a fully fledged system, 42 | such as :pep:`The Update Framework <458>`, 43 | instead. 44 | 45 | Due to the issues it has and the lack of use it is the opinion of this PEP 46 | that it does not provide any practical benefit to justify the additional 47 | complexity. 48 | 49 | 50 | Plan for Deprecation & Removal 51 | ============================== 52 | 53 | Immediately upon the acceptance of this PEP the Mirror Authenticity API will 54 | be considered deprecated and mirroring agents and installation tools should 55 | stop accessing it. 56 | 57 | Instead of actually removing it from the current code base (PyPI 1.0) the 58 | current work to replace PyPI 1.0 with a new code base (PyPI 2.0) will simply 59 | not implement this API. This would cause the API to be "removed" when the 60 | switch from 1.0 to 2.0 occurs. 61 | 62 | If PyPI 2.0 has not been deployed in place of PyPI 1.0 by Sept 01 2014 then 63 | this PEP will be implemented in the PyPI 1.0 code base instead (by removing 64 | the associated code). 65 | 66 | No changes will be required in the installers, however :pep:`381` compliant 67 | mirroring clients, such as 68 | `bandersnatch `_ and 69 | `pep381client `_ will need to be 70 | updated to no longer attempt to mirror the /serversig URLs. 71 | 72 | 73 | Copyright 74 | ========= 75 | 76 | This document has been placed in the public domain. 77 | 78 | 79 | 80 | .. 81 | Local Variables: 82 | mode: indented-text 83 | indent-tabs-mode: nil 84 | sentence-end-double-space: t 85 | fill-column: 70 86 | coding: utf-8 87 | End: 88 | -------------------------------------------------------------------------------- /peps/pep-0478.rst: -------------------------------------------------------------------------------- 1 | PEP: 478 2 | Title: Python 3.5 Release Schedule 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Larry Hastings 6 | Status: Final 7 | Type: Informational 8 | Topic: Release 9 | Content-Type: text/x-rst 10 | Created: 22-Sep-2014 11 | Python-Version: 3.5 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | This document describes the development and release schedule for 18 | Python 3.5. The schedule primarily concerns itself with PEP-sized 19 | items. 20 | 21 | .. Small features may be added up to the first beta 22 | release. Bugs may be fixed until the final release, 23 | which is planned for September 2015. 24 | 25 | 26 | Release Manager and Crew 27 | ======================== 28 | 29 | - 3.5 Release Manager: Larry Hastings 30 | - Windows installers: Steve Dower 31 | - Mac installers: Ned Deily 32 | - Documentation: Georg Brandl 33 | 34 | 35 | Release Schedule 36 | ================ 37 | 38 | Python 3.5 has now reached its end-of-life and has been retired. 39 | No more releases will be made. 40 | 41 | These are all the historical releases of Python 3.5, 42 | including their release dates. 43 | 44 | - 3.5.0 alpha 1: February 8, 2015 45 | - 3.5.0 alpha 2: March 9, 2015 46 | - 3.5.0 alpha 3: March 29, 2015 47 | - 3.5.0 alpha 4: April 19, 2015 48 | - 3.5.0 beta 1: May 24, 2015 49 | (Beta 1 is also "feature freeze"--no new features beyond this point.) 50 | - 3.5.0 beta 2: May 31, 2015 51 | - 3.5.0 beta 3: July 5, 2015 52 | - 3.5.0 beta 4: July 26, 2015 53 | - 3.5.0 release candidate 1: August 10, 2015 54 | - 3.5.0 release candidate 2: August 25, 2015 55 | - 3.5.0 release candidate 3: September 7, 2015 56 | - 3.5.0 final: September 13, 2015 57 | - 3.5.1 release candidate 1: November 22, 2015 58 | - 3.5.1 final: December 6, 2015 59 | - 3.5.2 release candidate 1: Sunday, June 12, 2016 60 | - 3.5.2 final: Sunday, June 26, 2016 61 | - 3.5.3 candidate 1: January 2, 2017 62 | - 3.5.3 final: January 17, 2017 63 | - 3.5.4 candidate 1: July 25, 2017 64 | - 3.5.4 final: August 8, 2017 65 | - 3.5.5 candidate 1: January 23, 2018 66 | - 3.5.5 final: February 4, 2018 67 | - 3.5.6 candidate 1: July 19, 2018 68 | - 3.5.6 final: August 2, 2018 69 | - 3.5.7 candidate 1: March 4, 2019 70 | - 3.5.7 final: March 18, 2019 71 | - 3.5.8 candidate 1: September 9, 2019 72 | - 3.5.8 candidate 2: October 12, 2019 73 | - 3.5.8 final: October 29, 2019 74 | - 3.5.9 final: November 1, 2019 75 | - 3.5.10 rc1: August 21, 2020 76 | - 3.5.10 final: September 5, 2020 77 | 78 | 79 | 80 | 81 | Features for 3.5 82 | ================ 83 | 84 | * :pep:`441`, improved Python zip application support 85 | * :pep:`448`, additional unpacking generalizations 86 | * :pep:`461`, "%-formatting" for bytes and bytearray objects 87 | * :pep:`465`, a new operator ("@") for matrix multiplication 88 | * :pep:`471`, os.scandir(), a fast new directory traversal function 89 | * :pep:`475`, adding support for automatic retries of interrupted system calls 90 | * :pep:`479`, change StopIteration handling inside generators 91 | * :pep:`484`, the typing module, a new standard for type annotations 92 | * :pep:`485`, math.isclose(), a function for testing approximate equality 93 | * :pep:`486`, making the Windows Python launcher aware of virtual environments 94 | * :pep:`488`, eliminating .pyo files 95 | * :pep:`489`, a new and improved mechanism for loading extension modules 96 | * :pep:`492`, coroutines with async and await syntax 97 | 98 | 99 | Copyright 100 | ========= 101 | 102 | This document has been placed in the public domain. 103 | 104 | 105 | 106 | .. 107 | Local Variables: 108 | mode: indented-text 109 | indent-tabs-mode: nil 110 | sentence-end-double-space: t 111 | fill-column: 70 112 | coding: utf-8 113 | End: 114 | -------------------------------------------------------------------------------- /peps/pep-0480-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0480-1.png -------------------------------------------------------------------------------- /peps/pep-0495-daylightsavings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0495-daylightsavings.png -------------------------------------------------------------------------------- /peps/pep-0505/test.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This file is used for testing find-pep505.py. 3 | 4 | nc_* and Nc* are examples of null coalescing. 5 | sn_* and Sn* are examples of save navigation. 6 | ''' 7 | 8 | def nc_ifblock1(a=None): 9 | if a is None: 10 | a = 'foo' 11 | 12 | def nc_ifblock2(a=None): 13 | if a is not None: 14 | pass 15 | else: 16 | a = 'foo' 17 | 18 | class NcIfBlock3: 19 | def __init__(self, a=None): 20 | if a is None: 21 | self.b = {} 22 | else: 23 | self.b = a 24 | 25 | class NcIfBlock4: 26 | def __init__(self, a=None): 27 | if a is not None: 28 | self.b = a 29 | else: 30 | self.b = {} 31 | 32 | def nc_or1(a=None): 33 | return a or 'foo' 34 | 35 | def nc_or2(a=None): 36 | return a or [] 37 | 38 | def nc_ternary1(a=None): 39 | return a if a is not None else 'foo' 40 | 41 | def nc_ternary2(a=None): 42 | return 'foo' if a is None else a 43 | 44 | def sn_and1(a=None): 45 | return a and a.foo 46 | 47 | def sn_and2(a=None): 48 | return a and a['foo'] 49 | 50 | def sn_and3(a=None): 51 | return a and a.foo() 52 | 53 | def sn_and3(a=None): 54 | return a and a.foo.bar 55 | 56 | class SnIfBlock1: 57 | def __init__(self, a=None): 58 | if a is not None: 59 | a.foo() 60 | 61 | class SnIfBlock2: 62 | def __init__(self, a=None): 63 | if a is None: 64 | pass 65 | else: 66 | a.foo() 67 | 68 | class SnIfBlock3: 69 | def __init__(self, a=None): 70 | if a is None: 71 | b = 'foo' 72 | else: 73 | b = a.foo 74 | 75 | class SnIfBlock4: 76 | def __init__(self, a=None): 77 | if a is None: 78 | b = 'foo' 79 | else: 80 | b = a['foo'] 81 | 82 | def sn_ternary1(a=None): 83 | return a.foo if a is not None else None 84 | 85 | def sn_ternary2(a=None): 86 | return None if a is None else a.foo 87 | 88 | def sn_ternary3(a=None): 89 | return a['foo'] if a is not None else None 90 | 91 | def sn_ternary4(a=None): 92 | return None if a is None else a.foo() 93 | -------------------------------------------------------------------------------- /peps/pep-0525-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0525-1.png -------------------------------------------------------------------------------- /peps/pep-0550-hamt_vs_dict-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0550-hamt_vs_dict-v2.png -------------------------------------------------------------------------------- /peps/pep-0550-hamt_vs_dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0550-hamt_vs_dict.png -------------------------------------------------------------------------------- /peps/pep-0550-lookup_hamt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0550-lookup_hamt.png -------------------------------------------------------------------------------- /peps/pep-0559.rst: -------------------------------------------------------------------------------- 1 | PEP: 559 2 | Title: Built-in noop() 3 | Author: Barry Warsaw 4 | Status: Rejected 5 | Type: Standards Track 6 | Content-Type: text/x-rst 7 | Created: 08-Sep-2017 8 | Python-Version: 3.7 9 | Post-History: 09-Sep-2017 10 | Resolution: https://mail.python.org/pipermail/python-dev/2017-September/149438.html 11 | 12 | 13 | Abstract 14 | ======== 15 | 16 | This PEP proposes adding a new built-in function called ``noop()`` which does 17 | nothing but return ``None``. 18 | 19 | 20 | Rationale 21 | ========= 22 | 23 | It is trivial to implement a no-op function in Python. It's so easy in fact 24 | that many people do it many times over and over again. It would be useful in 25 | many cases to have a common built-in function that does nothing. 26 | 27 | One use case would be for :pep:`553`, where you could set the breakpoint 28 | environment variable to the following in order to effectively disable it:: 29 | 30 | $ setenv PYTHONBREAKPOINT=noop 31 | 32 | 33 | Implementation 34 | ============== 35 | 36 | The Python equivalent of the ``noop()`` function is exactly:: 37 | 38 | def noop(*args, **kws): 39 | return None 40 | 41 | The C built-in implementation is available as a pull request [1]_. 42 | 43 | 44 | Rejected alternatives 45 | ===================== 46 | 47 | ``noop()`` returns something 48 | ---------------------------- 49 | 50 | YAGNI. 51 | 52 | This is rejected because it complicates the semantics. For example, if you 53 | always return both ``*args`` and ``**kws``, what do you return when none of 54 | those are given? Returning a tuple of ``((), {})`` is kind of ugly, but 55 | provides consistency. But you might also want to just return ``None`` since 56 | that's also conceptually what the function was passed. 57 | 58 | Or, what if you pass in exactly one positional argument, e.g. ``noop(7)``. Do 59 | you return ``7`` or ``((7,), {})``? And so on. 60 | 61 | The author claims that you won't ever need the return value of ``noop()`` so 62 | it will always return ``None``. 63 | 64 | Coghlan's Dialogs (edited for formatting): 65 | 66 | My counterargument to this would be ``map(noop, iterable)``, 67 | ``sorted(iterable, key=noop)``, etc. (``filter``, ``max``, and 68 | ``min`` all accept callables that accept a single argument, as do 69 | many of the itertools operations). 70 | 71 | Making ``noop()`` a useful default function in those cases just 72 | needs the definition to be:: 73 | 74 | def noop(*args, **kwds): 75 | return args[0] if args else None 76 | 77 | The counterargument to the counterargument is that using ``None`` 78 | as the default in all these cases is going to be faster, since it 79 | lets the algorithm skip the callback entirely, rather than calling 80 | it and having it do nothing useful. 81 | 82 | 83 | References 84 | ========== 85 | 86 | .. [1] https://github.com/python/cpython/pull/3480 87 | 88 | 89 | Copyright 90 | ========= 91 | 92 | This document has been placed in the public domain. 93 | 94 | 95 | 96 | .. 97 | Local Variables: 98 | mode: indented-text 99 | indent-tabs-mode: nil 100 | sentence-end-double-space: t 101 | fill-column: 70 102 | coding: utf-8 103 | End: 104 | -------------------------------------------------------------------------------- /peps/pep-0602-example-release-calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0602-example-release-calendar.png -------------------------------------------------------------------------------- /peps/pep-0602-example-release-calendar.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0602-example-release-calendar.pptx -------------------------------------------------------------------------------- /peps/pep-0602-overlapping-support-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0602-overlapping-support-matrix.png -------------------------------------------------------------------------------- /peps/pep-0602-overlapping-support-matrix.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0602-overlapping-support-matrix.pptx -------------------------------------------------------------------------------- /peps/pep-0603-hamt_vs_dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0603-hamt_vs_dict.png -------------------------------------------------------------------------------- /peps/pep-0603-lookup_hamt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0603-lookup_hamt.png -------------------------------------------------------------------------------- /peps/pep-0605-example-release-calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0605-example-release-calendar.png -------------------------------------------------------------------------------- /peps/pep-0605-overlapping-support-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0605-overlapping-support-matrix.png -------------------------------------------------------------------------------- /peps/pep-0605/example-release-calendar.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0605/example-release-calendar.odp -------------------------------------------------------------------------------- /peps/pep-0605/overlapping-support-matrix.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-0605/overlapping-support-matrix.odp -------------------------------------------------------------------------------- /peps/pep-0619.rst: -------------------------------------------------------------------------------- 1 | PEP: 619 2 | Title: Python 3.10 Release Schedule 3 | Author: Pablo Galindo Salgado 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 25-May-2020 8 | Python-Version: 3.10 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.10. The schedule primarily concerns itself with PEP-sized 16 | items. 17 | 18 | .. Small features may be added up to the first beta 19 | release. Bugs may be fixed until the final release, 20 | which is planned for October 2021. 21 | 22 | Release Manager and Crew 23 | ======================== 24 | - 3.10 Release Manager: Pablo Galindo Salgado 25 | - Windows installers: Steve Dower 26 | - Mac installers: Ned Deily 27 | - Documentation: Julien Palard 28 | 29 | 30 | Release Schedule 31 | ================ 32 | 33 | 3.10.0 schedule 34 | --------------- 35 | 36 | Note: the dates below use a 17-month development period that results 37 | in a 12-month release cadence between feature versions, as defined by 38 | :pep:`602`. 39 | 40 | Actual: 41 | 42 | - 3.10 development begins: Monday, 2020-05-18 43 | - 3.10.0 alpha 1: Monday, 2020-10-05 44 | - 3.10.0 alpha 2: Tuesday, 2020-11-03 45 | - 3.10.0 alpha 3: Monday, 2020-12-07 46 | - 3.10.0 alpha 4: Monday, 2021-01-04 47 | - 3.10.0 alpha 5: Wednesday, 2021-02-03 48 | - 3.10.0 alpha 6: Monday, 2021-03-01 49 | - 3.10.0 alpha 7: Tuesday, 2021-04-06 50 | - 3.10.0 beta 1: Monday, 2021-05-03 51 | (No new features beyond this point.) 52 | - 3.10.0 beta 2: Monday, 2021-05-31 53 | - 3.10.0 beta 3: Thursday, 2021-06-17 54 | - 3.10.0 beta 4: Saturday, 2021-07-10 55 | - 3.10.0 candidate 1: Tuesday, 2021-08-03 56 | - 3.10.0 candidate 2: Tuesday, 2021-09-07 57 | - 3.10.0 final: Monday, 2021-10-04 58 | 59 | Bugfix releases 60 | --------------- 61 | 62 | Actual: 63 | 64 | - 3.10.1: Monday, 2021-12-06 65 | - 3.10.2: Friday, 2022-01-14 66 | - 3.10.3: Wednesday, 2022-03-16 67 | - 3.10.4: Thursday, 2022-03-24 68 | - 3.10.5: Monday, 2022-06-06 69 | - 3.10.6: Tuesday, 2022-08-02 70 | - 3.10.7: Tuesday, 2022-09-06 71 | - 3.10.8: Tuesday, 2022-10-11 72 | - 3.10.9: Tuesday, 2022-12-06 73 | - 3.10.10: Wednesday, 2023-02-08 74 | - 3.10.11: Wednesday, 2023-04-05 (final regular bugfix release with binary 75 | installers) 76 | 77 | Source-only security fix releases 78 | --------------------------------- 79 | 80 | Provided irregularly on an "as-needed" basis until October 2026. 81 | 82 | - 3.10.12: Tuesday, 2023-06-06 83 | - 3.10.13: Thursday, 2023-08-24 84 | - 3.10.14: Tuesday, 2024-03-19 85 | 86 | 3.10 Lifespan 87 | ------------- 88 | 89 | 3.10 will receive bugfix updates approximately every 2 months for 90 | approximately 18 months. Some time after the release of 3.11.0 final, 91 | the 11th and final 3.10 bugfix update will be released. After that, 92 | it is expected that security updates (source only) will be released 93 | until 5 years after the release of 3.10 final, so until approximately 94 | October 2026. 95 | 96 | 97 | Features for 3.10 98 | ================= 99 | 100 | Some of the notable features of Python 3.10 include: 101 | 102 | * :pep:`604`, Allow writing union types as ``X | Y`` 103 | * :pep:`612`, Parameter Specification Variables 104 | * :pep:`613`, Explicit Type Aliases 105 | * :pep:`618`, Add Optional Length-Checking To ``zip`` 106 | * :pep:`626`, Precise line numbers for debugging and other tools 107 | * :pep:`634`, :pep:`635`, :pep:`636`, Structural Pattern Matching 108 | * :pep:`644`, Require OpenSSL 1.1.1 or newer 109 | * :pep:`624`, Remove Py_UNICODE encoder APIs 110 | * :pep:`597`, Add optional EncodingWarning 111 | 112 | 113 | Copyright 114 | ========= 115 | 116 | This document has been placed in the public domain. 117 | -------------------------------------------------------------------------------- /peps/pep-0628.rst: -------------------------------------------------------------------------------- 1 | PEP: 628 2 | Title: Add ``math.tau`` 3 | Version: $Revision$ 4 | Last-Modified: $Date$ 5 | Author: Alyssa Coghlan 6 | Status: Final 7 | Type: Standards Track 8 | Content-Type: text/x-rst 9 | Created: 28-Jun-2011 10 | Python-Version: 3.6 11 | Post-History: 28-Jun-2011 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | In honour of Tau Day 2011, this PEP proposes the addition of the circle 18 | constant ``math.tau`` to the Python standard library. 19 | 20 | The concept of ``tau`` (``τ``) is based on the observation that the ratio of a 21 | circle's circumference to its radius is far more fundamental and interesting 22 | than the ratio between its circumference and diameter. It is simply a matter 23 | of assigning a name to the value ``2 * pi`` (``2π``). 24 | 25 | 26 | PEP Acceptance 27 | ============== 28 | 29 | This PEP is now `accepted`_ and ``math.tau`` will be a part of Python 3.6. 30 | Happy birthday Alyssa! 31 | 32 | The idea in this PEP has been implemented in the auspiciously named 33 | `issue 12345`_. 34 | 35 | .. _accepted: https://bugs.python.org/issue12345#msg272287 36 | .. _issue 12345: http://bugs.python.org/issue12345 37 | 38 | 39 | The Rationale for Tau 40 | ===================== 41 | 42 | ``pi`` is defined as the ratio of a circle's circumference to its diameter. 43 | However, a circle is defined by its centre point and its *radius*. This is 44 | shown clearly when we note that the parameter of integration to go from a 45 | circle's circumference to its area is the radius, not the diameter. If we 46 | use the diameter instead we have to divide by four to get rid of the 47 | extraneous multiplier. 48 | 49 | When working with radians, it is trivial to convert any given fraction of a 50 | circle to a value in radians in terms of ``tau``. A quarter circle is 51 | ``tau/4``, a half circle is ``tau/2``, seven 25ths is ``7*tau/25``, etc. In 52 | contrast with the equivalent expressions in terms of ``pi`` (``pi/2``, ``pi``, 53 | ``14*pi/25``), the unnecessary and needlessly confusing multiplication by 54 | two is gone. 55 | 56 | 57 | Other Resources 58 | =============== 59 | 60 | I've barely skimmed the surface of the many examples put forward to point out 61 | just how much *easier* and more *sensible* many aspects of mathematics become 62 | when conceived in terms of ``tau`` rather than ``pi``. If you don't find my 63 | specific examples sufficiently persuasive, here are some more resources that 64 | may be of interest: 65 | 66 | * Michael Hartl is the primary instigator of Tau Day in his `Tau Manifesto`_ 67 | * Bob Palais, the author of the original mathematics journal article 68 | highlighting the problems with ``pi`` has `a page of resources`_ on the 69 | topic 70 | * For those that prefer videos to written text, `Pi is wrong!`_ and 71 | `Pi is (still) wrong`_ are available on YouTube 72 | 73 | .. _Tau Manifesto: http://tauday.com/ 74 | .. _Pi is (still) wrong: http://www.youtube.com/watch?v=jG7vhMMXagQ 75 | .. _Pi is wrong!: http://www.youtube.com/watch?v=IF1zcRoOVN0 76 | .. _a page of resources: http://www.math.utah.edu/~palais/pi.html 77 | 78 | 79 | Copyright 80 | ========= 81 | 82 | This document has been placed in the public domain. 83 | 84 | .. 85 | Local Variables: 86 | mode: indented-text 87 | indent-tabs-mode: nil 88 | sentence-end-double-space: t 89 | fill-column: 70 90 | coding: utf-8 91 | End: 92 | -------------------------------------------------------------------------------- /peps/pep-0662/pep-0662-editable.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "http://pypa.io/editables.json", 4 | "type": "object", 5 | "title": "Virtual wheel editable schema.", 6 | "required": ["version", "scheme"], 7 | "properties": { 8 | "version": { 9 | "$id": "#/properties/version", 10 | "type": "integer", 11 | "minimum": 1, 12 | "maximum": 1, 13 | "title": "The version of the schema." 14 | }, 15 | "scheme": { 16 | "$id": "#/properties/scheme", 17 | "type": "object", 18 | "title": "Files to expose.", 19 | "required": ["purelib", "platlib", "data", "headers", "scripts"], 20 | "properties": { 21 | "purelib": { "$ref": "#/$defs/mapping" }, 22 | "platlib": { "$ref": "#/$defs/mapping" }, 23 | "data": { "$ref": "#/$defs/mapping" }, 24 | "headers": { "$ref": "#/$defs/mapping" }, 25 | "scripts": { "$ref": "#/$defs/mapping" } 26 | }, 27 | "additionalProperties": true 28 | } 29 | }, 30 | "additionalProperties": true, 31 | "$defs": { 32 | "mapping": { 33 | "type": "object", 34 | "description": "A mapping of source to target paths. The source is absolute path, the destination is relative path.", 35 | "additionalProperties": true 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /peps/pep-0664.rst: -------------------------------------------------------------------------------- 1 | PEP: 664 2 | Title: Python 3.11 Release Schedule 3 | Author: Pablo Galindo Salgado 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 12-Jul-2021 8 | Python-Version: 3.11 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.11. The schedule primarily concerns itself with PEP-sized 16 | items. 17 | 18 | .. Small features may be added up to the first beta 19 | release. Bugs may be fixed until the final release, 20 | which is planned for October 2022. 21 | 22 | Release Manager and Crew 23 | ======================== 24 | 25 | - 3.11 Release Manager: Pablo Galindo Salgado 26 | - Windows installers: Steve Dower 27 | - Mac installers: Ned Deily 28 | - Documentation: Julien Palard 29 | 30 | 31 | Release Schedule 32 | ================ 33 | 34 | 3.11.0 schedule 35 | --------------- 36 | 37 | Note: the dates below use a 17-month development period that results 38 | in a 12-month release cadence between feature versions, as defined by 39 | :pep:`602`. 40 | 41 | Actual: 42 | 43 | - 3.11 development begins: Monday, 2021-05-03 44 | - 3.11.0 alpha 1: Tuesday, 2021-10-05 45 | - 3.11.0 alpha 2: Tuesday, 2021-11-02 46 | - 3.11.0 alpha 3: Wednesday, 2021-12-08 47 | - 3.11.0 alpha 4: Friday, 2022-01-14 48 | - 3.11.0 alpha 5: Thursday, 2022-02-03 49 | - 3.11.0 alpha 6: Monday, 2022-03-07 50 | - 3.11.0 alpha 7: Tuesday, 2022-04-05 51 | - 3.11.0 beta 1: Sunday, 2022-05-08 52 | (No new features beyond this point.) 53 | - 3.11.0 beta 2: Tuesday, 2022-05-31 54 | - 3.11.0 beta 3: Wednesday, 2022-06-01 55 | - 3.11.0 beta 4: Monday, 2022-07-11 56 | - 3.11.0 beta 5: Tuesday, 2022-07-26 57 | - 3.11.0 candidate 1: Monday, 2022-08-08 58 | - 3.11.0 candidate 2: Monday, 2022-09-12 59 | - 3.11.0 final: Monday, 2022-10-24 60 | 61 | Bugfix releases 62 | --------------- 63 | 64 | Actual: 65 | 66 | - 3.11.1: Tuesday, 2022-12-06 67 | - 3.11.2: Wednesday, 2023-02-08 68 | - 3.11.3: Wednesday, 2023-04-05 69 | - 3.11.4: Tuesday, 2023-06-06 70 | - 3.11.5: Thursday, 2023-08-24 71 | - 3.11.6: Monday, 2023-10-02 72 | - 3.11.7: Monday, 2023-12-04 73 | - 3.11.8: Tuesday, 2024-02-06 74 | - 3.11.9: Tuesday, 2024-04-02 (final regular bugfix release with binary 75 | installers) 76 | 77 | 3.11 Lifespan 78 | ------------- 79 | 80 | 3.11 will receive bugfix updates approximately every 2 months for 81 | approximately 18 months. Some time after the release of 3.12.0 final, 82 | the ninth and final 3.11 bugfix update will be released. After that, 83 | it is expected that security updates (source only) will be released 84 | until 5 years after the release of 3.11.0 final, so until approximately 85 | October 2027. 86 | 87 | 88 | Features for 3.11 89 | ================= 90 | 91 | Some of the notable features of Python 3.11 include: 92 | 93 | * :pep:`654`, Exception Groups and ``except*``. 94 | * :pep:`657`, Enhanced error locations in tracebacks. 95 | * :pep:`680`, Support for parsing TOML in the standard library 96 | * Python 3.11 is up to 10-60% faster than Python 3.10. On average, we measured 97 | a 1.25x speedup on the standard benchmark suite. See `Faster CPython 98 | `__ for 99 | details. 100 | 101 | Typing features: 102 | 103 | * :pep:`646`, Variadic generics. 104 | * :pep:`655`, Marking individual TypedDict items as required or potentially-missing. 105 | * :pep:`673`, Self type. 106 | * :pep:`675`, Arbitrary literal string type. 107 | * :pep:`681`, Dataclass transforms 108 | 109 | Copyright 110 | ========= 111 | 112 | This document has been placed in the public domain. 113 | -------------------------------------------------------------------------------- /peps/pep-0693.rst: -------------------------------------------------------------------------------- 1 | PEP: 693 2 | Title: Python 3.12 Release Schedule 3 | Author: Thomas Wouters 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 24-May-2022 8 | Python-Version: 3.12 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.12. 16 | 17 | Release Manager and Crew 18 | ======================== 19 | 20 | - 3.12 Release Manager: Thomas Wouters 21 | - Windows installers: Steve Dower 22 | - Mac installers: Ned Deily 23 | - Documentation: Julien Palard 24 | 25 | Release Schedule 26 | ================ 27 | 28 | 3.12.0 schedule 29 | --------------- 30 | 31 | Note: the dates below use a 17-month development period that results 32 | in a 12-month release cadence between feature versions, as defined by 33 | :pep:`602`. 34 | 35 | Actual: 36 | 37 | - 3.12 development begins: Sunday, 2022-05-08 38 | - 3.12.0 alpha 1: Monday, 2022-10-24 39 | - 3.12.0 alpha 2: Monday, 2022-11-14 40 | - 3.12.0 alpha 3: Tuesday, 2022-12-06 41 | - 3.12.0 alpha 4: Tuesday, 2023-01-10 42 | - 3.12.0 alpha 5: Tuesday, 2023-02-07 43 | - 3.12.0 alpha 6: Tuesday, 2023-03-07 44 | - 3.12.0 alpha 7: Tuesday, 2023-04-04 45 | - 3.12.0 beta 1: Monday, 2023-05-22 46 | (No new features beyond this point.) 47 | - 3.12.0 beta 2: Tuesday, 2023-06-06 48 | - 3.12.0 beta 3: Monday, 2023-06-19 49 | - 3.12.0 beta 4: Tuesday, 2023-07-11 50 | - 3.12.0 candidate 1: Sunday, 2023-08-06 51 | - 3.12.0 candidate 2: Wednesday, 2023-09-06 52 | - 3.12.0 candidate 3: Tuesday, 2023-09-19 53 | - 3.12.0 final: Monday, 2023-10-02 54 | 55 | Bugfix releases 56 | --------------- 57 | 58 | Actual: 59 | 60 | - 3.12.1: Thursday, 2023-12-07 61 | - 3.12.2: Tuesday, 2024-02-06 62 | - 3.12.3: Tuesday, 2024-04-09 63 | 64 | Expected: 65 | 66 | - 3.12.4: Tuesday, 2024-06-04 67 | - 3.12.5: Tuesday, 2024-08-06 68 | - 3.12.6: Tuesday, 2024-10-01 69 | - 3.12.7: Tuesday, 2024-12-03 70 | - 3.12.8: Tuesday, 2025-02-04 71 | - 3.12.9: Tuesday, 2025-04-08 72 | 73 | Source-only security fix releases 74 | --------------------------------- 75 | 76 | Provided irregularly on an as-needed basis until October 2028. 77 | 78 | 3.12 Lifespan 79 | ------------- 80 | 81 | 3.12 will receive bugfix updates approximately every 2 months for 82 | approximately 18 months. Some time after the release of 3.13.0 final, 83 | the ninth and final 3.12 bugfix update will be released. After that, 84 | it is expected that security updates (source only) will be released 85 | until 5 years after the release of 3.12.0 final, so until approximately 86 | October 2028. 87 | 88 | 89 | Features for 3.12 90 | ================= 91 | 92 | New features can be found in `What’s New In Python 3.12 93 | `__. 94 | 95 | 96 | Copyright 97 | ========= 98 | 99 | This document is placed in the public domain or under the CC0-1.0-Universal 100 | license, whichever is more permissive. 101 | 102 | 103 | -------------------------------------------------------------------------------- /peps/pep-0719.rst: -------------------------------------------------------------------------------- 1 | PEP: 719 2 | Title: Python 3.13 Release Schedule 3 | Author: Thomas Wouters 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 26-May-2023 8 | Python-Version: 3.13 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.13. 16 | 17 | Release Manager and Crew 18 | ======================== 19 | 20 | - 3.13 Release Manager: Thomas Wouters 21 | - Windows installers: Steve Dower 22 | - Mac installers: Ned Deily 23 | - Documentation: Julien Palard 24 | 25 | 26 | Release Schedule 27 | ================ 28 | 29 | 3.13.0 schedule 30 | --------------- 31 | 32 | Note: the dates below use a 17-month development period that results 33 | in a 12-month release cadence between feature versions, as defined by 34 | :pep:`602`. 35 | 36 | Actual: 37 | 38 | - 3.13 development begins: Monday, 2023-05-22 39 | - 3.13.0 alpha 1: Friday, 2023-10-13 40 | - 3.13.0 alpha 2: Wednesday, 2023-11-22 41 | - 3.13.0 alpha 3: Wednesday, 2024-01-17 42 | - 3.13.0 alpha 4: Thursday, 2024-02-15 43 | - 3.13.0 alpha 5: Tuesday, 2024-03-12 44 | - 3.13.0 alpha 6: Tuesday, 2024-04-09 45 | - 3.13.0 beta 1: Wednesday, 2024-05-08 46 | (No new features beyond this point.) 47 | 48 | Expected: 49 | 50 | - 3.13.0 beta 2: Tuesday, 2024-06-04 51 | - 3.13.0 beta 3: Tuesday, 2024-06-25 52 | - 3.13.0 beta 4: Tuesday, 2024-07-16 53 | - 3.13.0 candidate 1: Tuesday, 2024-07-30 54 | - 3.13.0 candidate 2: Tuesday, 2024-09-03 55 | - 3.13.0 final: Tuesday, 2024-10-01 56 | 57 | Subsequent bugfix releases every two months. 58 | 59 | 60 | 3.13 Lifespan 61 | ------------- 62 | 63 | 3.13 will receive bugfix updates approximately every 2 months for 64 | approximately 24 months. Around the time of the release of 3.15.0 final, the 65 | final 3.13 bugfix update will be released. After that, it is expected that 66 | security updates (source only) will be released until 5 years after the 67 | release of 3.13.0 final, so until approximately October 2029. 68 | 69 | 70 | Copyright 71 | ========= 72 | 73 | This document is placed in the public domain or under the CC0-1.0-Universal 74 | license, whichever is more permissive. 75 | 76 | 77 | -------------------------------------------------------------------------------- /peps/pep-0745.rst: -------------------------------------------------------------------------------- 1 | PEP: 745 2 | Title: Python 3.14 Release Schedule 3 | Author: Hugo van Kemenade 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 24-Apr-2024 8 | Python-Version: 3.14 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.14. 16 | 17 | Release Manager and Crew 18 | ======================== 19 | 20 | - 3.14 Release Manager: Hugo van Kemenade 21 | - Windows installers: Steve Dower 22 | - Mac installers: Ned Deily 23 | - Documentation: Julien Palard 24 | 25 | 26 | Release Schedule 27 | ================ 28 | 29 | 3.14.0 schedule 30 | --------------- 31 | 32 | The dates below use a 17-month development period that results 33 | in a 12-month release cadence between feature versions, as defined by 34 | :pep:`602`. 35 | 36 | Expected: 37 | 38 | - 3.14 development begins: Tuesday, 2024-05-07 39 | - 3.14.0 alpha 1: Tuesday, 2024-10-15 40 | - 3.14.0 alpha 2: Tuesday, 2024-11-19 41 | - 3.14.0 alpha 3: Tuesday, 2024-12-17 42 | - 3.14.0 alpha 4: Tuesday, 2025-01-14 43 | - 3.14.0 alpha 5: Tuesday, 2025-02-11 44 | - 3.14.0 alpha 6: Friday, 2025-03-14 45 | - 3.14.0 alpha 7: Tuesday, 2025-04-08 46 | - 3.14.0 beta 1: Tuesday, 2025-05-06 47 | (No new features beyond this point.) 48 | - 3.14.0 beta 2: Tuesday, 2025-05-27 49 | - 3.14.0 beta 3: Tuesday, 2025-06-17 50 | - 3.14.0 beta 4: Tuesday, 2025-07-08 51 | - 3.14.0 candidate 1: Tuesday, 2025-07-22 52 | - 3.14.0 candidate 2: Tuesday, 2025-08-26 53 | - 3.14.0 final: Wednesday, 2025-10-01 54 | 55 | Subsequent bugfix releases every two months. 56 | 57 | 58 | 3.14 lifespan 59 | ------------- 60 | 61 | Python 3.14 will receive bugfix updates approximately every two months for 62 | approximately 24 months. Around the time of the release of 3.16.0 final, the 63 | final 3.14 bugfix update will be released. After that, it is expected that 64 | security updates (source only) will be released until five years after the 65 | release of 3.14.0 final, so until approximately October 2030. 66 | 67 | 68 | Copyright 69 | ========= 70 | 71 | This document is placed in the public domain or under the 72 | CC0-1.0-Universal license, whichever is more permissive. 73 | -------------------------------------------------------------------------------- /peps/pep-0801.rst: -------------------------------------------------------------------------------- 1 | PEP: 801 2 | Title: Reserved 3 | Author: Barry Warsaw 4 | Status: Active 5 | Type: Informational 6 | Content-Type: text/x-rst 7 | Created: 21-Jun-2018 8 | 9 | 10 | Abstract 11 | ======== 12 | 13 | This PEP is reserved for future use, because 14 | `We are the 801 `_. 15 | Contact the author for details. 16 | 17 | 18 | Copyright 19 | ========= 20 | 21 | This document has been placed in the public domain. 22 | 23 | 24 | .. 25 | Local Variables: 26 | mode: indented-text 27 | indent-tabs-mode: nil 28 | sentence-end-double-space: t 29 | fill-column: 70 30 | coding: utf-8 31 | End: 32 | -------------------------------------------------------------------------------- /peps/pep-3147-1.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-3147-1.dia -------------------------------------------------------------------------------- /peps/pep-3147-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zikc2023/peps/b14f4e77a1ee59b2ac9541737f1b8a718c668512/peps/pep-3147-1.png -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | # https://docs.pytest.org/en/7.3.x/reference/reference.html#command-line-flags 3 | addopts = 4 | -r a 5 | --strict-config 6 | --strict-markers 7 | --import-mode=importlib 8 | --cov check_peps --cov pep_sphinx_extensions 9 | --cov-report html --cov-report xml 10 | empty_parameter_set_mark = fail_at_collect 11 | filterwarnings = 12 | error 13 | minversion = 6.0 14 | testpaths = pep_sphinx_extensions 15 | xfail_strict = True 16 | disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements for building PEPs with Sphinx 2 | Pygments >= 2.9.0 3 | # Sphinx 6.1.0 broke copying images in parallel builds; fixed in 6.1.2 4 | # See https://github.com/sphinx-doc/sphinx/pull/11100 5 | Sphinx >= 5.1.1, != 6.1.0, != 6.1.1 6 | docutils >= 0.19.0 7 | 8 | sphinx-autobuild 9 | 10 | # For tests 11 | pytest 12 | pytest-cov 13 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | requires = 3 | tox>=4.2 4 | env_list = 5 | py{313, 312, 311, 310, 39} 6 | no_package = true 7 | 8 | [testenv] 9 | deps = 10 | -rrequirements.txt 11 | pass_env = 12 | FORCE_COLOR 13 | commands = 14 | python -bb -X dev -W error -m pytest {posargs} 15 | --------------------------------------------------------------------------------