├── .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 as Accepted or Rejected.md │ ├── Mark a PEP as 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 ├── api │ └── index.rst ├── 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-0739 │ ├── example.json │ └── python-build-info-v1.0.schema.json ├── pep-0740.rst ├── pep-0741.rst ├── pep-0742.rst ├── pep-0743.rst ├── pep-0744.rst ├── pep-0745.rst ├── pep-0746.rst ├── pep-0747.rst ├── pep-0748.rst ├── pep-0749.rst ├── pep-0750.rst ├── pep-0751.rst ├── pep-0752.rst ├── pep-0753.rst ├── pep-0754.rst ├── pep-0755.rst ├── pep-0756.rst ├── pep-0757.rst ├── pep-0758.rst ├── pep-0759.rst ├── pep-0760.rst ├── pep-0761.rst ├── pep-0762.rst ├── pep-0763.rst ├── pep-0764.rst ├── pep-0765.rst ├── pep-0766.rst ├── pep-0767.rst ├── pep-0768.rst ├── pep-0769.rst ├── pep-0770.rst ├── pep-0771.rst ├── pep-0772.rst ├── pep-0773.rst ├── pep-0774.rst ├── pep-0775.rst ├── pep-0776.rst ├── pep-0777.rst ├── pep-0777 │ ├── appendix-dl-by-installer.png │ ├── appendix-dl-by-pip-version.png │ └── appendix-pypi-download-analysis.rst ├── pep-0779.rst ├── pep-0780.rst ├── pep-0781.rst ├── pep-0782.rst ├── pep-0783.rst ├── pep-0784.rst ├── pep-0785.rst ├── pep-0787.rst ├── pep-0788.rst ├── pep-0789.rst ├── pep-0790.rst ├── pep-0791.rst ├── pep-0793.rst ├── pep-0793 │ └── examplemodule.c ├── pep-0801.rst ├── pep-2026.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-789-example-no-yield.png ├── pep-789-example-yield-allowed.png ├── pep-789-example-yield-errors.png ├── 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 └── pep-8106.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 | 19 | >>> "abd\ 20 | 21 | * ``Is``, ``IsNot``, ``In``, and ``NotIn`` are not supported 22 | -------------------------------------------------------------------------------- /.codespell/ignore-words.txt: -------------------------------------------------------------------------------- 1 | adaptee 2 | ancilliary 3 | ans 4 | anull 5 | arithmetics 6 | asend 7 | ba 8 | ccompiler 9 | checkin 10 | clos 11 | complies 12 | crate 13 | dedented 14 | discernable 15 | dota 16 | extraversion 17 | falsy 18 | fo 19 | groth 20 | iif 21 | implementor 22 | implementors 23 | loath 24 | nd 25 | ned 26 | re-usable 27 | re-use 28 | re-used 29 | re-using 30 | recuse 31 | reenable 32 | referencable 33 | therefor 34 | warmup 35 | -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | skip = ./.git,./.codespellrc,./build,./ruff_cache,./.venv 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 as 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`` field points directly to SC/PEP Delegate official acceptance/rejected post, including the date (e.g. `` `01-Jan-2000 <https://discuss.python.org/t/12345/100>`__ ``) 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 as 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 as 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 | if: github.event.repository.fork == false 20 | steps: 21 | - uses: readthedocs/actions/preview@v1 22 | with: 23 | project-slug: "pep-previews" 24 | single-version: "true" 25 | -------------------------------------------------------------------------------- /.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 | with: 24 | persist-credentials: false 25 | 26 | - name: Set up Python 3 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: "3.x" 30 | 31 | - name: Run pre-commit hooks 32 | uses: tox-dev/action-pre-commit-uv@v1 33 | 34 | - name: Check spelling 35 | uses: tox-dev/action-pre-commit-uv@v1 36 | with: 37 | extra_args: --all-files --hook-stage manual codespell || true 38 | -------------------------------------------------------------------------------- /.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.14-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 | 43 | steps: 44 | - uses: actions/checkout@v4 45 | with: 46 | persist-credentials: false 47 | 48 | - name: Set up Python ${{ matrix.python-version }} 49 | uses: actions/setup-python@v5 50 | with: 51 | python-version: ${{ matrix.python-version }} 52 | allow-prereleases: true 53 | 54 | - name: Install uv 55 | uses: hynek/setup-cached-uv@v2 56 | with: 57 | cache-dependency-path: | 58 | requirements.txt 59 | 60 | - name: Run tests with tox 61 | run: | 62 | uvx --with tox-uv tox -e py -- -v --cov-report term 63 | 64 | - name: Upload coverage 65 | uses: codecov/codecov-action@v5 66 | with: 67 | flags: ${{ matrix.os }} 68 | name: ${{ matrix.os }} Python ${{ matrix.python-version }} 69 | token: ${{ secrets.CODECOV_ORG_TOKEN }} 70 | -------------------------------------------------------------------------------- /.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 28 | /peps/numerical.rst 29 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | 4 | minimum_pre_commit_version: '2.8.2' 5 | 6 | default_language_version: 7 | python: python3 8 | 9 | default_stages: [pre-commit] 10 | 11 | 12 | repos: 13 | # General file checks and fixers 14 | - repo: https://github.com/pre-commit/pre-commit-hooks 15 | rev: v5.0.0 16 | hooks: 17 | - id: end-of-file-fixer 18 | name: "Ensure files end with a single newline" 19 | - id: mixed-line-ending 20 | name: "Normalize mixed line endings" 21 | args: [--fix=lf] 22 | - id: trailing-whitespace 23 | name: "Remove trailing whitespace" 24 | 25 | - id: file-contents-sorter 26 | name: "Sort codespell ignore list" 27 | files: '.codespell/ignore-words.txt' 28 | 29 | - id: check-case-conflict 30 | name: "Check for case conflicts" 31 | - id: check-merge-conflict 32 | name: "Check for merge conflict markers" 33 | - id: check-executables-have-shebangs 34 | name: "Check that executables have shebangs" 35 | - id: check-shebang-scripts-are-executable 36 | name: "Check that shebangs are executable" 37 | 38 | - id: check-vcs-permalinks 39 | name: "Check that VCS links are permalinks" 40 | 41 | # - id: check-ast 42 | # name: "Check Python AST" 43 | - id: check-json 44 | name: "Check JSON" 45 | - id: check-toml 46 | name: "Check TOML" 47 | - id: check-yaml 48 | name: "Check YAML" 49 | 50 | - repo: https://github.com/psf/black-pre-commit-mirror 51 | rev: 24.10.0 52 | hooks: 53 | - id: black 54 | name: "Format with Black" 55 | args: 56 | - '--target-version=py39' 57 | - '--target-version=py310' 58 | files: '^(peps/conf\.py|pep_sphinx_extensions/tests/.*)$' 59 | 60 | - repo: https://github.com/astral-sh/ruff-pre-commit 61 | rev: v0.7.0 62 | hooks: 63 | - id: ruff 64 | name: "Lint with Ruff" 65 | args: 66 | - '--exit-non-zero-on-fix' 67 | files: '^pep_sphinx_extensions/tests/' 68 | 69 | - repo: https://github.com/tox-dev/tox-ini-fmt 70 | rev: 1.4.1 71 | hooks: 72 | - id: tox-ini-fmt 73 | name: "Format tox.ini" 74 | 75 | - repo: https://github.com/sphinx-contrib/sphinx-lint 76 | rev: v1.0.0 77 | hooks: 78 | - id: sphinx-lint 79 | name: "Sphinx lint" 80 | args: ["--disable=trailing-whitespace"] 81 | 82 | # RST checks 83 | - repo: https://github.com/pre-commit/pygrep-hooks 84 | rev: v1.10.0 85 | hooks: 86 | - id: rst-backticks 87 | name: "Check RST: No single backticks" 88 | 89 | - id: rst-inline-touching-normal 90 | name: "Check RST: No backticks touching text" 91 | 92 | - id: rst-directive-colons 93 | name: "Check RST: 2 colons after directives" 94 | 95 | # Manual codespell check 96 | - repo: https://github.com/codespell-project/codespell 97 | rev: v2.3.0 98 | hooks: 99 | - id: codespell 100 | name: "Check for common misspellings in text files" 101 | require_serial: true 102 | stages: [manual] 103 | 104 | # Local checks for PEP headers and more 105 | - repo: local 106 | hooks: 107 | # Hook to run "check-peps.py" 108 | - id: "check-peps" 109 | name: "Check PEPs for metadata and content enforcement" 110 | entry: "python check-peps.py" 111 | language: "python" 112 | files: '^peps/pep-\d{4}\.rst$' 113 | require_serial: true 114 | -------------------------------------------------------------------------------- /.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-lts-latest 9 | tools: 10 | python: "3" 11 | 12 | commands: 13 | - asdf plugin add uv 14 | - asdf install uv latest 15 | - asdf global uv latest 16 | - make dirhtml JOBS=$(nproc) BUILDDIR=_readthedocs/html 17 | 18 | sphinx: 19 | builder: dirhtml 20 | configuration: peps/conf.py 21 | 22 | search: 23 | ignore: ['*'] 24 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | The 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/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/pep_sphinx_extensions/pep_theme/static/og-image.png -------------------------------------------------------------------------------- /pep_sphinx_extensions/pep_theme/static/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/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 | for (const closeButton of document.getElementsByClassName("close-button")) { 26 | closeButton.addEventListener("click", () => { 27 | // search the button's ancestors for a ``sticky-banner`` element. 28 | const stickyBanner = closeButton.closest(".sticky-banner"); 29 | if (stickyBanner) stickyBanner.remove(); 30 | }); 31 | } 32 | 33 | adjustBannerMargin(); 34 | document.addEventListener("resize", adjustBannerMargin); 35 | document.addEventListener("load", adjustBannerMargin); 36 | }); 37 | -------------------------------------------------------------------------------- /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/partials/icons.html: -------------------------------------------------------------------------------- 1 | {# Adapted from Just the Docs → Furo #} 2 | <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> 3 | <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> 4 | <title>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 | numerical_index_text = writer.PEPZeroWriter().write_numerical_index(peps) 67 | subindices.update_sphinx("numerical", numerical_index_text, docnames, env) 68 | 69 | pep0_text = writer.PEPZeroWriter().write_pep0(peps, builder=env.settings["builder"]) 70 | pep0_path = subindices.update_sphinx("pep-0000", pep0_text, docnames, env) 71 | peps.append(parser.PEP(pep0_path)) 72 | 73 | subindices.generate_subindices(SUBINDICES_BY_TOPIC, peps, docnames, env) 74 | 75 | write_peps_json(peps, Path(app.outdir)) 76 | -------------------------------------------------------------------------------- /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/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/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/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/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 | from ..conftest import PEP_ROOT 6 | 7 | PEP_9002 = Path(__file__).parent.parent / "peps" / "pep-9002.rst" 8 | 9 | 10 | def test_with_fake_pep(): 11 | content = PEP_9002.read_text(encoding="utf-8").splitlines() 12 | warnings = list(check_peps.check_peps(PEP_9002, content)) 13 | assert warnings == [ 14 | (1, "PEP must begin with the 'PEP:' header"), 15 | (6, "Must not have invalid header: Version"), 16 | (9, "Must not have duplicate header: Sponsor "), 17 | (10, "Must not have invalid header: Horse-Guards"), 18 | (15, "Must not have invalid header: Content-Type"), 19 | (1, "Must have required header: PEP"), 20 | (1, "Must have required header: Type"), 21 | ( 22 | 1, 23 | "Headers must be in PEP 12 order. Correct order: Title, Author, " 24 | "Sponsor, BDFL-Delegate, Discussions-To, Status, Topic, Requires, " 25 | "Created, Python-Version, Post-History, Resolution", 26 | ), 27 | (4, "Author continuation lines must end with a comma"), 28 | (5, "Author line must not be over-indented"), 29 | (7, "Python-Version major part must be 1, 2, or 3: 4.0"), 30 | (8, "Sponsor entries must begin with a valid 'Name': ''"), 31 | (9, "Sponsor entries must begin with a valid 'Name': ''"), 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 | (16, "PEP references must be separated by comma-spaces (', ')"), 40 | (17, "Discussions-To must be a valid thread URL, mailing list, or 'Pending'"), 41 | (18, "Post-History must be a 'DD-mmm-YYYY' date: '2-Feb-2000'"), 42 | (18, "Post-History must be a valid thread URL"), 43 | (19, "Post-History must be a 'DD-mmm-YYYY' date: '3-Mar-2001'"), 44 | (19, "Post-History must be a valid thread URL"), 45 | (20, "Resolution must be a valid thread URL"), 46 | (23, "Use the :pep:`NNN` role to refer to PEPs"), 47 | ] 48 | 49 | 50 | def test_skip_direct_pep_link_check(): 51 | filename = PEP_ROOT / "pep-0009.rst" # in SKIP_DIRECT_PEP_LINK_CHECK 52 | content = filename.read_text(encoding="utf-8").splitlines() 53 | warnings = list(check_peps.check_peps(filename, content)) 54 | assert warnings == [] 55 | -------------------------------------------------------------------------------- /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/api/index.rst: -------------------------------------------------------------------------------- 1 | PEPs API 2 | ======== 3 | 4 | There is a read-only JSON document of every published PEP available at 5 | https://peps.python.org/api/peps.json. 6 | 7 | Each PEP is represented as a JSON object, keyed by the PEP number. 8 | The structure of each JSON object is as follows: 9 | 10 | .. code-block:: typescript 11 | 12 | { 13 | "": { 14 | "number": integer, // always identical to 15 | "title": string, 16 | "authors": string, 17 | "discussions_to": string | null, 18 | "status": "Accepted" | "Active" | "Deferred" | "Draft" | "Final" | "Provisional" | "Rejected" | "Superseded" | "Withdrawn", 19 | "type": "Informational" | "Process" | "Standards Track", 20 | "topic": "governance" | "packaging" | "release" | "typing" | "", 21 | "created": string, 22 | "python_version": string | null, 23 | "post_history": string | null, 24 | "resolution": string | null, 25 | "requires": string | null, 26 | "replaces": string | null, 27 | "superseded_by": string | null, 28 | "author_names": Array, 29 | "url": string 30 | }, 31 | } 32 | 33 | Date values are formatted as DD-MMM-YYYY, 34 | and multiple dates are combined in a comma-separated list. 35 | 36 | A selection of example PEPs are shown here, 37 | illustrating some of the possible values for each field: 38 | 39 | .. code-block:: json 40 | 41 | { 42 | "12": { 43 | "number": 12, 44 | "title": "Sample reStructuredText PEP Template", 45 | "authors": "David Goodger, Barry Warsaw, Brett Cannon", 46 | "discussions_to": null, 47 | "status": "Active", 48 | "type": "Process", 49 | "topic": "", 50 | "created": "05-Aug-2002", 51 | "python_version": null, 52 | "post_history": "`30-Aug-2002 `__", 53 | "resolution": null, 54 | "requires": null, 55 | "replaces": null, 56 | "superseded_by": null, 57 | "author_names": [ 58 | "David Goodger", 59 | "Barry Warsaw", 60 | "Brett Cannon" 61 | ], 62 | "url": "https://peps.python.org/pep-0012/" 63 | }, 64 | "160": { 65 | "number": 160, 66 | "title": "Python 1.6 Release Schedule", 67 | "authors": "Fred L. Drake, Jr.", 68 | "discussions_to": null, 69 | "status": "Final", 70 | "type": "Informational", 71 | "topic": "release", 72 | "created": "25-Jul-2000", 73 | "python_version": "1.6", 74 | "post_history": null, 75 | "resolution": null, 76 | "requires": null, 77 | "replaces": null, 78 | "superseded_by": null, 79 | "author_names": [ 80 | "Fred L. Drake, Jr." 81 | ], 82 | "url": "https://peps.python.org/pep-0160/" 83 | }, 84 | "3124": { 85 | "number": 3124, 86 | "title": "Overloading, Generic Functions, Interfaces, and Adaptation", 87 | "authors": "Phillip J. Eby", 88 | "discussions_to": "python-3000@python.org", 89 | "status": "Deferred", 90 | "type": "Standards Track", 91 | "topic": "", 92 | "created": "28-Apr-2007", 93 | "python_version": null, 94 | "post_history": "30-Apr-2007", 95 | "resolution": null, 96 | "requires": "3107, 3115, 3119", 97 | "replaces": "245, 246", 98 | "superseded_by": null, 99 | "author_names": [ 100 | "Phillip J. Eby" 101 | ], 102 | "url": "https://peps.python.org/pep-3124/" 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /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 | api/* 18 | topic/* 19 | numerical 20 | pep-* 21 | -------------------------------------------------------------------------------- /peps/pep-0002.rst: -------------------------------------------------------------------------------- 1 | PEP: 2 2 | Title: Procedure for Adding New Modules 3 | Author: Brett Cannon , 4 | Martijn Faassen 5 | Status: Active 6 | Type: Process 7 | Created: 07-Jul-2001 8 | Post-History: 07-Jul-2001, 09-Mar-2002 9 | 10 | 11 | Introduction 12 | ============ 13 | 14 | The Python Standard Library contributes significantly to Python's 15 | success. The language comes with "batteries included", so it is easy 16 | for people to become productive with just the standard library alone. 17 | It is therefore important that the usefulness of the standard library 18 | be maintained. 19 | 20 | Due to the visibility and importance of the standard library, it must 21 | be maintained thoughtfully. As such, any code within it must be 22 | maintained by Python's development team which leads to a perpetual 23 | cost to each addition made. There is also added cognitive load for 24 | users in familiarizing themselves with what is in the standard 25 | library to be considered. 26 | 27 | New functionality is commonly added to the library in the form of new 28 | modules. This PEP will describe the procedure for the *addition* of 29 | new modules. :pep:`4` deals with procedures for deprecation of modules; 30 | the *removal* of old and unused modules from the standard library. 31 | 32 | 33 | Acceptance Procedure 34 | ==================== 35 | 36 | For top-level modules/packages, a PEP is required. The procedure for 37 | writing a PEP is covered in :pep:`1`. 38 | 39 | For submodules of a preexisting package in the standard library, 40 | additions are at the discretion of the general Python development team 41 | and its members. 42 | 43 | General guidance on what modules typically are accepted into the 44 | standard library, the overall process, etc. are covered in the 45 | `developer's guide `_. 46 | 47 | 48 | Maintenance Procedure 49 | ===================== 50 | 51 | Anything accepted into the standard library is expected to be 52 | primarily maintained there, within Python's development infrastructure. 53 | While some members of the development team may choose to maintain a 54 | backport of a module outside of the standard library, it is up to them 55 | to keep their external code in sync as appropriate. 56 | 57 | 58 | Copyright 59 | ========= 60 | 61 | This document has been placed in the public domain. 62 | -------------------------------------------------------------------------------- /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 | Author: Brett Cannon , Martin von Löwis 4 | Status: Active 5 | Type: Process 6 | Created: 01-Oct-2000 7 | Post-History: 8 | 9 | 10 | Introduction 11 | ============ 12 | 13 | When new modules were added to the standard Python library in the 14 | past, it was not possible to foresee whether they would still be 15 | useful in the future. Even though Python "Comes With Batteries 16 | Included", batteries may discharge over time. Carrying old modules 17 | around is a burden on the maintainer, especially when there is no 18 | interest in the module anymore. 19 | 20 | At the same time, removing a module from the distribution is 21 | difficult, as it is not known in general whether anybody is still 22 | using it. This PEP defines a procedure for removing modules from the 23 | standard Python library. Usage of a module may be 'deprecated', which 24 | means that it may be removed from a future Python release. 25 | 26 | 27 | Procedure for declaring a module deprecated 28 | =========================================== 29 | 30 | To remove a top-level module/package from the standard library, a PEP 31 | is required. The deprecation process is outlined in :pep:`387`. 32 | 33 | For removing a submodule of a package in the standard library, 34 | :pep:`387` must be followed, but a PEP is not required. 35 | 36 | 37 | Copyright 38 | ========= 39 | 40 | This document has been placed in the public domain. 41 | -------------------------------------------------------------------------------- /peps/pep-0005.rst: -------------------------------------------------------------------------------- 1 | PEP: 5 2 | Title: Guidelines for Language Evolution 3 | Author: Paul Prescod 4 | Status: Superseded 5 | Type: Process 6 | Created: 26-Oct-2000 7 | Post-History: 8 | Superseded-By: 387 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | In the natural evolution of programming languages it is sometimes 15 | necessary to make changes that modify the behavior of older programs. 16 | This PEP proposes a policy for implementing these changes in a manner 17 | respectful of the installed base of Python users. 18 | 19 | 20 | Implementation Details 21 | ====================== 22 | 23 | Implementation of this PEP requires the addition of a formal warning 24 | and deprecation facility that will be described in another proposal. 25 | 26 | 27 | Scope 28 | ===== 29 | 30 | These guidelines apply to future versions of Python that introduce 31 | backward-incompatible behavior. Backward incompatible behavior is a 32 | major deviation in Python interpretation from an earlier behavior 33 | described in the standard Python documentation. Removal of a feature 34 | also constitutes a change of behavior. 35 | 36 | This PEP does not replace or preclude other compatibility strategies 37 | such as dynamic loading of backwards-compatible parsers. On the other 38 | hand, if execution of "old code" requires a special switch or pragma 39 | then that is indeed a change of behavior from the point of view of the 40 | user and that change should be implemented according to these 41 | guidelines. 42 | 43 | In general, common sense must prevail in the implementation of these 44 | guidelines. For instance changing "sys.copyright" does not constitute 45 | a backwards-incompatible change of behavior! 46 | 47 | 48 | Steps For Introducing Backwards-Incompatible Features 49 | ===================================================== 50 | 51 | 1. Propose backwards-incompatible behavior in a PEP. The PEP must 52 | include a section on backwards compatibility that describes in 53 | detail a plan to complete the remainder of these steps. 54 | 55 | 2. Once the PEP is accepted as a productive direction, implement an 56 | alternate way to accomplish the task previously provided by the 57 | feature that is being removed or changed. For instance if the 58 | addition operator were scheduled for removal, a new version of 59 | Python could implement an "add()" built-in function. 60 | 61 | 3. Formally deprecate the obsolete construct in the Python 62 | documentation. 63 | 64 | 4. Add an optional warning mode to the parser that will inform users 65 | when the deprecated construct is used. In other words, all 66 | programs that will behave differently in the future must trigger 67 | warnings in this mode. Compile-time warnings are preferable to 68 | runtime warnings. The warning messages should steer people from 69 | the deprecated construct to the alternative construct. 70 | 71 | 5. There must be at least a one-year transition period between the 72 | release of the transitional version of Python and the release of 73 | the backwards incompatible version. Users will have at least a 74 | year to test their programs and migrate them from use of the 75 | deprecated construct to the alternative one. 76 | -------------------------------------------------------------------------------- /peps/pep-0010.rst: -------------------------------------------------------------------------------- 1 | PEP: 10 2 | Title: Voting Guidelines 3 | Author: Barry Warsaw 4 | Status: Active 5 | Type: Process 6 | Created: 07-Mar-2002 7 | Post-History: 07-Mar-2002 8 | 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP outlines the python-dev voting guidelines. These guidelines 15 | serve to provide feedback or gauge the "wind direction" on a 16 | particular proposal, idea, or feature. They don't have a binding 17 | force. 18 | 19 | 20 | Rationale 21 | ========= 22 | 23 | When a new idea, feature, patch, etc. is floated in the Python 24 | community, either through a PEP or on the mailing lists (most likely 25 | on python-dev [1]_), it is sometimes helpful to gauge the community's 26 | general sentiment. Sometimes people just want to register their 27 | opinion of an idea. Sometimes the BDFL wants to take a straw poll. 28 | Whatever the reason, these guidelines have been adopted so as to 29 | provide a common language for developers. 30 | 31 | While opinions are (sometimes) useful, but they are never binding. 32 | Opinions that are accompanied by rationales are always valued higher 33 | than bare scores (this is especially true with -1 votes). 34 | 35 | 36 | Voting Scores 37 | ============= 38 | 39 | The scoring guidelines are loosely derived from the Apache voting 40 | procedure [2]_, with of course our own spin on things. There are 4 41 | possible vote scores: 42 | 43 | - ``+1`` I like it 44 | 45 | - ``+0`` I don't care, but go ahead 46 | 47 | - ``-0`` I don't care, so why bother? 48 | 49 | - ``-1`` I hate it 50 | 51 | You may occasionally see wild flashes of enthusiasm (either for or 52 | against) with vote scores like +2, +1000, or -1000. These aren't 53 | really valued much beyond the above scores, but it's nice to see 54 | people get excited about such geeky stuff. 55 | 56 | 57 | References 58 | ========== 59 | 60 | .. [1] Python Developer's Guide, 61 | (http://www.python.org/dev/) 62 | 63 | .. [2] Apache Project Guidelines and Voting Rules 64 | (http://httpd.apache.org/dev/guidelines.html) 65 | 66 | 67 | Copyright 68 | ========= 69 | 70 | This document has been placed in the public domain. 71 | -------------------------------------------------------------------------------- /peps/pep-0012/pep-NNNN.rst: -------------------------------------------------------------------------------- 1 | PEP: 2 | Title: 3 | Author: 4 | Sponsor: 5 | PEP-Delegate: 6 | Discussions-To: Pending 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 | Created: 19-Aug-2004 7 | Post-History: 22-Aug-2004 8 | 9 | 10 | Abstract 11 | ======== 12 | 13 | Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding 14 | principles for Python's design into 20 aphorisms, only 19 of which 15 | have been written down. 16 | 17 | 18 | The Zen of Python 19 | ================= 20 | 21 | .. code-block:: text 22 | 23 | Beautiful is better than ugly. 24 | Explicit is better than implicit. 25 | Simple is better than complex. 26 | Complex is better than complicated. 27 | Flat is better than nested. 28 | Sparse is better than dense. 29 | Readability counts. 30 | Special cases aren't special enough to break the rules. 31 | Although practicality beats purity. 32 | Errors should never pass silently. 33 | Unless explicitly silenced. 34 | In the face of ambiguity, refuse the temptation to guess. 35 | There should be one-- and preferably only one --obvious way to do it. 36 | Although that way may not be obvious at first unless you're Dutch. 37 | Now is better than never. 38 | Although never is often better than *right* now. 39 | If the implementation is hard to explain, it's a bad idea. 40 | If the implementation is easy to explain, it may be a good idea. 41 | Namespaces are one honking great idea -- let's do more of those! 42 | 43 | 44 | Easter Egg 45 | ========== 46 | 47 | .. code-block:: pycon 48 | 49 | >>> import this 50 | 51 | 52 | References 53 | ========== 54 | 55 | Originally posted to comp.lang.python/python-list@python.org under a 56 | thread called `"The Way of Python" 57 | `__ 58 | 59 | 60 | Copyright 61 | ========= 62 | 63 | This document has been placed in the public domain. 64 | -------------------------------------------------------------------------------- /peps/pep-0160.rst: -------------------------------------------------------------------------------- 1 | PEP: 160 2 | Title: Python 1.6 Release Schedule 3 | Author: Fred L. Drake, Jr. 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Created: 25-Jul-2000 8 | Python-Version: 1.6 9 | Post-History: 10 | 11 | 12 | Introduction 13 | ============ 14 | 15 | This PEP describes the Python 1.6 release schedule. The CVS 16 | revision history of this file contains the definitive historical 17 | record. 18 | 19 | This release will be produced by BeOpen PythonLabs staff for the 20 | Corporation for National Research Initiatives (CNRI). 21 | 22 | 23 | Schedule 24 | ======== 25 | 26 | * August 1: 1.6 beta 1 release (planned). 27 | * August 3: 1.6 beta 1 release (actual). 28 | * August 15: 1.6 final release (planned). 29 | * September 5: 1.6 final release (actual). 30 | 31 | 32 | Features 33 | ======== 34 | 35 | A number of features are required for Python 1.6 in order to 36 | fulfill the various promises that have been made. The following 37 | are required to be fully operational, documented, and forward 38 | compatible with the plans for Python 2.0: 39 | 40 | * Unicode support: The Unicode object defined for Python 2.0 must be provided, 41 | including all methods and codec support. 42 | 43 | * SRE: Fredrik Lundh's new regular expression engine will be used 44 | to provide support for both 8-bit strings and Unicode strings. It must pass 45 | the regression test used for the pcre-based version of the re module. 46 | 47 | * The curses module was in the middle of a transformation to a package, so the 48 | final form was adopted. 49 | 50 | 51 | Mechanism 52 | ========= 53 | 54 | The release will be created as a branch from the development tree 55 | rooted at CNRI's close of business on 16 May 2000. Patches 56 | required from more recent checkins will be merged in by moving the 57 | branch tag on individual files whenever possible in order to 58 | reduce mailing list clutter and avoid divergent and incompatible 59 | implementations. 60 | 61 | The branch tag is "cnri-16-start". 62 | 63 | Patches and features will be merged to the extent required to pass 64 | regression tests in effect on 16 May 2000. 65 | 66 | The beta release is tagged "r16b1" in the CVS repository, and the 67 | final Python 1.6 release is tagged "release16" in the repository. 68 | 69 | 70 | Copyright 71 | ========= 72 | 73 | This document has been placed in the public domain. 74 | -------------------------------------------------------------------------------- /peps/pep-0202.rst: -------------------------------------------------------------------------------- 1 | PEP: 202 2 | Title: List Comprehensions 3 | Author: Barry Warsaw 4 | Status: Final 5 | Type: Standards Track 6 | Created: 13-Jul-2000 7 | Python-Version: 2.0 8 | Post-History: 9 | 10 | 11 | Introduction 12 | ============ 13 | 14 | This PEP describes a proposed syntactical extension to Python, list 15 | comprehensions. 16 | 17 | 18 | The Proposed Solution 19 | ===================== 20 | 21 | It is proposed to allow conditional construction of list literals using for and 22 | if clauses. They would nest in the same way for loops and if statements nest 23 | now. 24 | 25 | 26 | Rationale 27 | ========= 28 | 29 | List comprehensions provide a more concise way to create lists in situations 30 | where ``map()`` and ``filter()`` and/or nested loops would currently be used. 31 | 32 | 33 | Examples 34 | ======== 35 | 36 | :: 37 | 38 | >>> print [i for i in range(10)] 39 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 40 | 41 | >>> print [i for i in range(20) if i%2 == 0] 42 | [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 43 | 44 | >>> nums = [1, 2, 3, 4] 45 | >>> fruit = ["Apples", "Peaches", "Pears", "Bananas"] 46 | >>> print [(i, f) for i in nums for f in fruit] 47 | [(1, 'Apples'), (1, 'Peaches'), (1, 'Pears'), (1, 'Bananas'), 48 | (2, 'Apples'), (2, 'Peaches'), (2, 'Pears'), (2, 'Bananas'), 49 | (3, 'Apples'), (3, 'Peaches'), (3, 'Pears'), (3, 'Bananas'), 50 | (4, 'Apples'), (4, 'Peaches'), (4, 'Pears'), (4, 'Bananas')] 51 | >>> print [(i, f) for i in nums for f in fruit if f[0] == "P"] 52 | [(1, 'Peaches'), (1, 'Pears'), 53 | (2, 'Peaches'), (2, 'Pears'), 54 | (3, 'Peaches'), (3, 'Pears'), 55 | (4, 'Peaches'), (4, 'Pears')] 56 | >>> print [(i, f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1] 57 | [(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')] 58 | >>> print [i for i in zip(nums, fruit) if i[0]%2==0] 59 | [(2, 'Peaches'), (4, 'Bananas')] 60 | 61 | 62 | Reference Implementation 63 | ======================== 64 | 65 | List comprehensions become part of the Python language with release 2.0, 66 | documented in [1]_. 67 | 68 | 69 | BDFL Pronouncements 70 | =================== 71 | * The syntax proposed above is the Right One. 72 | 73 | * The form ``[x, y for ...]`` is disallowed; one is required to write 74 | ``[(x, y) for ...]``. 75 | 76 | * The form ``[... for x... for y...]`` nests, with the last index 77 | varying fastest, just like nested for loops. 78 | 79 | 80 | References 81 | ========== 82 | 83 | .. [1] http://docs.python.org/reference/expressions.html#list-displays 84 | -------------------------------------------------------------------------------- /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 | Created: 31-Jul-2000 7 | Python-Version: 2.1 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | Python's interactive mode is one of the implementation's great 15 | strengths -- being able to write expressions on the command line 16 | and get back a meaningful output. However, the output function 17 | cannot be all things to all people, and the current output 18 | function too often falls short of this goal. This PEP describes a 19 | way to provides alternatives to the built-in display function in 20 | Python, so users will have control over the output from the 21 | interactive interpreter. 22 | 23 | 24 | Interface 25 | ========= 26 | 27 | The current Python solution has worked for many users, and this 28 | should not break it. Therefore, in the default configuration, 29 | nothing will change in the REPL loop. To change the way the 30 | interpreter prints interactively entered expressions, users 31 | will have to rebind ``sys.displayhook`` to a callable object. 32 | The result of calling this object with the result of the 33 | interactively entered expression should be print-able, 34 | and this is what will be printed on ``sys.stdout``. 35 | 36 | 37 | Solution 38 | ======== 39 | 40 | The bytecode ``PRINT_EXPR`` will call ``sys.displayhook(POP())``. 41 | A ``displayhook()`` will be added to the sys builtin module, which is 42 | equivalent to:: 43 | 44 | import __builtin__ 45 | def displayhook(o): 46 | if o is None: 47 | return 48 | __builtin__._ = None 49 | print `o` 50 | __builtin__._ = o 51 | 52 | 53 | Jython Issues 54 | ============= 55 | 56 | The method ``Py.printResult`` will be similarly changed. 57 | -------------------------------------------------------------------------------- /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 | Created: 11-Dec-2000 7 | Python-Version: 2.1 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP describes a command-line driven online help facility for 15 | Python. The facility should be able to build on existing 16 | documentation facilities such as the Python documentation and 17 | docstrings. It should also be extensible for new types and 18 | modules. 19 | 20 | 21 | Interactive use 22 | =============== 23 | 24 | Simply typing ``help`` describes the help function (through ``repr()`` 25 | overloading). 26 | 27 | ``help`` can also be used as a function. 28 | 29 | The function takes the following forms of input: 30 | 31 | * ``help( "string" )`` -- built-in topic or global 32 | * ``help( )`` -- docstring from object or type 33 | * ``help( "doc:filename" )`` -- filename from Python documentation 34 | 35 | If you ask for a global, it can be a fully-qualified name, such as:: 36 | 37 | help("xml.dom") 38 | 39 | You can also use the facility from a command-line:: 40 | 41 | python --help if 42 | 43 | In either situation, the output does paging similar to the ``more`` 44 | command. 45 | 46 | 47 | Implementation 48 | ============== 49 | 50 | The help function is implemented in an ``onlinehelp`` module which is 51 | demand-loaded. 52 | 53 | There should be options for fetching help information from 54 | environments other than the command line through the ``onlinehelp`` 55 | module:: 56 | 57 | onlinehelp.gethelp(object_or_string) -> string 58 | 59 | It should also be possible to override the help display function 60 | by assigning to ``onlinehelp.displayhelp(object_or_string)``. 61 | 62 | The module should be able to extract module information from 63 | either the HTML or LaTeX versions of the Python documentation. 64 | Links should be accommodated in a "lynx-like" manner. 65 | 66 | Over time, it should also be able to recognize when docstrings are 67 | in "special" syntaxes like structured text, HTML and LaTeX and 68 | decode them appropriately. 69 | 70 | A prototype implementation is available with the Python source 71 | distribution as ``nondist/sandbox/doctools/onlinehelp.py``. 72 | 73 | 74 | Built-in Topics 75 | =============== 76 | 77 | * ``help( "intro" )`` -- What is Python? Read this first! 78 | 79 | * ``help( "keywords" )`` -- What are the keywords? 80 | 81 | * ``help( "syntax" )`` -- What is the overall syntax? 82 | 83 | * ``help( "operators" )`` -- What operators are available? 84 | 85 | * ``help( "builtins" )`` -- What functions, types, etc. are built-in? 86 | 87 | * ``help( "modules" )`` -- What modules are in the standard library? 88 | 89 | * ``help( "copyright" )`` -- Who owns Python? 90 | 91 | * ``help( "moreinfo" )`` -- Where is there more information? 92 | 93 | * ``help( "changes" )`` -- What changed in Python 2.0? 94 | 95 | * ``help( "extensions" )`` -- What extensions are installed? 96 | 97 | * ``help( "faq" )`` -- What questions are frequently asked? 98 | 99 | * ``help( "ack" )`` -- Who has done work on Python lately? 100 | 101 | 102 | Security Issues 103 | =============== 104 | 105 | This module will attempt to import modules with the same names as 106 | requested topics. Don't use the modules if you are not confident 107 | that everything in your ``PYTHONPATH`` is from a trusted source. 108 | -------------------------------------------------------------------------------- /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 | Created: 11-Mar-2001 7 | Python-Version: 2.2 8 | Post-History: 16-Mar-2001 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | A :pep:`different PEP <239>` suggests adding a builtin rational type to 15 | Python. This PEP suggests changing the ddd.ddd float literal to a 16 | rational in Python, and modifying non-integer division to return 17 | it. 18 | 19 | 20 | BDFL Pronouncement 21 | ================== 22 | 23 | This PEP is rejected. The needs outlined in the rationale section 24 | have been addressed to some extent by the acceptance of :pep:`327` 25 | for decimal arithmetic. Guido also noted, "Rational arithmetic 26 | was the default 'exact' arithmetic in ABC and it did not work out as 27 | expected". See the python-dev discussion on 17 June 2005 [1]_. 28 | 29 | 30 | Rationale 31 | ========= 32 | 33 | Rational numbers are useful for exact and unsurprising arithmetic. 34 | They give the correct results people have been taught in various 35 | math classes. Making the "obvious" non-integer type one with more 36 | predictable semantics will surprise new programmers less than 37 | using floating point numbers. As quite a few posts on c.l.py and 38 | on tutor@python.org have shown, people often get bit by strange 39 | semantics of floating point numbers: for example, ``round(0.98, 2)`` 40 | still gives 0.97999999999999998. 41 | 42 | 43 | Proposal 44 | ======== 45 | 46 | Literals conforming to the regular expression ``'\d*.\d*'`` will be 47 | rational numbers. 48 | 49 | 50 | Backwards Compatibility 51 | ======================= 52 | 53 | The only backwards compatible issue is the type of literals 54 | mentioned above. The following migration is suggested: 55 | 56 | 1. The next Python after approval will allow 57 | ``from __future__ import rational_literals`` 58 | to cause all such literals to be treated as rational numbers. 59 | 60 | 2. Python 3.0 will have a warning, turned on by default, about 61 | such literals in the absence of a ``__future__`` statement. The 62 | warning message will contain information about the ``__future__`` 63 | statement, and indicate that to get floating point literals, 64 | they should be suffixed with "e0". 65 | 66 | 3. Python 3.1 will have the warning turned off by default. This 67 | warning will stay in place for 24 months, at which time the 68 | literals will be rationals and the warning will be removed. 69 | 70 | 71 | Common Objections 72 | ================= 73 | 74 | Rationals are slow and memory intensive! 75 | (Relax, I'm not taking floats away, I'm just adding two more characters. 76 | ``1e0`` will still be a float) 77 | 78 | Rationals must present themselves as a decimal float or they will be 79 | horrible for users expecting decimals (i.e. ``str(.5)`` should return ``'.5'`` and 80 | not ``'1/2'``). This means that many rationals must be truncated at some 81 | point, which gives us a new loss of precision. 82 | 83 | 84 | 85 | References 86 | ========== 87 | 88 | .. [1] Raymond Hettinger, Propose rejection of PEPs 239 and 240 -- a builtin 89 | rational type and rational literals 90 | https://mail.python.org/pipermail/python-dev/2005-June/054281.html 91 | 92 | 93 | Copyright 94 | ========= 95 | 96 | This document has been placed in the public domain. 97 | -------------------------------------------------------------------------------- /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 | Created: 17-Apr-2001 8 | Python-Version: 2.2 9 | Post-History: 14-Aug-2001 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This document describes the Python 2.2 development and release 16 | schedule. The schedule primarily concerns itself with PEP-sized 17 | items. Small bug fixes and changes will occur up until the first 18 | beta release. 19 | 20 | The schedule below represents the actual release dates of Python 21 | 2.2. Note that any subsequent maintenance releases of Python 2.2 22 | should be covered by separate PEPs. 23 | 24 | 25 | Release Schedule 26 | ================ 27 | 28 | Tentative future release dates. Note that we've slipped this 29 | compared to the schedule posted around the release of 2.2a1. 30 | 31 | * 21-Dec-2001: 2.2 [Released] (final release) 32 | * 14-Dec-2001: 2.2c1 [Released] 33 | * 14-Nov-2001: 2.2b2 [Released] 34 | * 19-Oct-2001: 2.2b1 [Released] 35 | * 28-Sep-2001: 2.2a4 [Released] 36 | * 7-Sep-2001: 2.2a3 [Released] 37 | * 22-Aug-2001: 2.2a2 [Released] 38 | * 18-Jul-2001: 2.2a1 [Released] 39 | 40 | 41 | Release Manager 42 | =============== 43 | 44 | Barry Warsaw was the Python 2.2 release manager. 45 | 46 | 47 | Release Mechanics 48 | ================= 49 | 50 | We experimented with a new mechanism for releases: a week before 51 | every alpha, beta or other release, we forked off a branch which 52 | became the release. Changes to the branch are limited to the 53 | release manager and his designated 'bots. This experiment was 54 | deemed a success and should be observed for future releases. See 55 | :pep:`101` for the actual release mechanics. 56 | 57 | 58 | New features for Python 2.2 59 | =========================== 60 | 61 | The following new features are introduced in Python 2.2. For a 62 | more detailed account, see Misc/NEWS [2]_ in the Python 63 | distribution, or Andrew Kuchling's "What's New in Python 2.2" 64 | document [3]_. 65 | 66 | - iterators (:pep:`234`) 67 | - generators (:pep:`255`) 68 | - unifying long ints and plain ints (:pep:`237`) 69 | - division (:pep:`238`) 70 | - unification of types and classes (:pep:`252`, :pep:`253`) 71 | 72 | 73 | References 74 | ========== 75 | 76 | .. [2] Misc/NEWS file from CVS 77 | 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 78 | 79 | .. [3] Andrew Kuchling, What's New in Python 2.2 80 | http://www.python.org/doc/2.2.1/whatsnew/whatsnew22.html 81 | 82 | 83 | Copyright 84 | ========= 85 | 86 | This document has been placed in the public domain. 87 | -------------------------------------------------------------------------------- /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 | Created: 18-Jun-2001 7 | Python-Version: 2.2 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP has not been written yet. Watch this space! 15 | 16 | 17 | Status 18 | ====== 19 | 20 | This PEP was a stub entry and eventually abandoned without having 21 | been filled-out. Substantially most of the intended functionality 22 | was implemented in Py2.2 with new-style types and classes. 23 | 24 | 25 | Copyright 26 | ========= 27 | 28 | This document has been placed in the public domain. 29 | -------------------------------------------------------------------------------- /peps/pep-0260.rst: -------------------------------------------------------------------------------- 1 | PEP: 260 2 | Title: Simplify xrange() 3 | Author: Guido van Rossum 4 | Status: Final 5 | Type: Standards Track 6 | Created: 26-Jun-2001 7 | Python-Version: 2.2 8 | Post-History: 26-Jun-2001 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP proposes to strip the ``xrange()`` object from some rarely 15 | used behavior like ``x[i:j]`` and ``x*n``. 16 | 17 | 18 | Problem 19 | ======= 20 | 21 | The ``xrange()`` function has one idiomatic use:: 22 | 23 | for i in xrange(...): ... 24 | 25 | However, the ``xrange()`` object has a bunch of rarely used behaviors 26 | that attempt to make it more sequence-like. These are so rarely 27 | used that historically they have has serious bugs (e.g. off-by-one 28 | errors) that went undetected for several releases. 29 | 30 | I claim that it's better to drop these unused features. This will 31 | simplify the implementation, testing, and documentation, and 32 | reduce maintenance and code size. 33 | 34 | 35 | Proposed Solution 36 | ================= 37 | 38 | I propose to strip the ``xrange()`` object to the bare minimum. The 39 | only retained sequence behaviors are ``x[i]``, ``len(x)``, and ``repr(x)``. 40 | In particular, these behaviors will be dropped: 41 | 42 | * ``x[i:j]`` (slicing) 43 | * ``x*n``, ``n*x`` (sequence-repeat) 44 | * ``cmp(x1, x2)`` (comparisons) 45 | * ``i in x`` (containment test) 46 | * ``x.tolist()`` method 47 | * ``x.start``, ``x.stop``, ``x.step`` attributes 48 | 49 | I also propose to change the signature of the ``PyRange_New()`` C API 50 | to remove the 4th argument (the repetition count). 51 | 52 | By implementing a custom iterator type, we could speed up the 53 | common use, but this is optional (the default sequence iterator 54 | does just fine). 55 | 56 | 57 | Scope 58 | ===== 59 | 60 | This PEP affects the ``xrange()`` built-in function and the 61 | ``PyRange_New()`` C API. 62 | 63 | 64 | Risks 65 | ===== 66 | 67 | Somebody's code could be relying on the extended code, and this 68 | code would break. However, given that historically bugs in the 69 | extended code have gone undetected for so long, it's unlikely that 70 | much code is affected. 71 | 72 | 73 | Transition 74 | ========== 75 | 76 | For backwards compatibility, the existing functionality will still 77 | be present in Python 2.2, but will trigger a warning. A year 78 | after Python 2.2 final is released (probably in 2.4) the 79 | functionality will be ripped out. 80 | 81 | 82 | Copyright 83 | ========= 84 | 85 | This document has been placed in the public domain. 86 | -------------------------------------------------------------------------------- /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 | Created: 21-Aug-2001 7 | Python-Version: 2.2 8 | Post-History: 9 | 10 | 11 | Notice 12 | ====== 13 | 14 | This PEP is withdrawn by the author. He writes: 15 | 16 | Removing duplicate elements from a list is a common task, but 17 | there are only two reasons I can see for making it a built-in. 18 | The first is if it could be done much faster, which isn't the 19 | case. The second is if it makes it significantly easier to 20 | write code. The introduction of ``sets.py`` eliminates this 21 | situation since creating a sequence without duplicates is just 22 | a matter of choosing a different data structure: a set instead 23 | of a list. 24 | 25 | As described in :pep:`218`, sets are being added to the standard 26 | library for Python 2.3. 27 | 28 | 29 | Abstract 30 | ======== 31 | 32 | This PEP proposes adding a method for removing duplicate elements to 33 | the list object. 34 | 35 | 36 | Rationale 37 | ========= 38 | 39 | Removing duplicates from a list is a common task. I think it is 40 | useful and general enough to belong as a method in list objects. 41 | It also has potential for faster execution when implemented in C, 42 | especially if optimization using hashing or sorted cannot be used. 43 | 44 | On comp.lang.python there are many, many, posts [1]_ asking about 45 | the best way to do this task. It's a little tricky to implement 46 | optimally and it would be nice to save people the trouble of 47 | figuring it out themselves. 48 | 49 | 50 | Considerations 51 | ============== 52 | 53 | Tim Peters suggests trying to use a hash table, then trying to 54 | sort, and finally falling back on brute force [2]_. Should uniq 55 | maintain list order at the expense of speed? 56 | 57 | Is it spelled 'uniq' or 'unique'? 58 | 59 | 60 | Reference Implementation 61 | ======================== 62 | 63 | I've written the brute force version. It's about 20 lines of code 64 | in ``listobject.c``. Adding support for hash table and sorted 65 | duplicate removal would only take another hour or so. 66 | 67 | 68 | References 69 | ========== 70 | 71 | .. [1] https://groups.google.com/forum/#!searchin/comp.lang.python/duplicates 72 | 73 | .. [2] Tim Peters unique() entry in the Python cookbook: 74 | http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560/index_txt 75 | 76 | 77 | Copyright 78 | ========= 79 | 80 | This document has been placed in the public domain. 81 | -------------------------------------------------------------------------------- /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 | Created: 15-Aug-2001 7 | Python-Version: 2.2 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | At present, setting the ``PYTHONPATH`` environment variable is the 15 | only method for defining additional Python module search 16 | directories. 17 | 18 | This PEP introduces the '-P' valued option to the python command 19 | as an alternative to ``PYTHONPATH``. 20 | 21 | 22 | Rationale 23 | ========= 24 | 25 | On Unix:: 26 | 27 | python -P $SOMEVALUE 28 | 29 | will be equivalent to:: 30 | 31 | env PYTHONPATH=$SOMEVALUE python 32 | 33 | On Windows 2K:: 34 | 35 | python -P %SOMEVALUE% 36 | 37 | will (almost) be equivalent to:: 38 | 39 | set __PYTHONPATH=%PYTHONPATH% && set PYTHONPATH=%SOMEVALUE%\ 40 | && python && set PYTHONPATH=%__PYTHONPATH% 41 | 42 | 43 | Other Information 44 | ================= 45 | 46 | This option is equivalent to the 'java -classpath' option. 47 | 48 | 49 | When to use this option 50 | ======================= 51 | 52 | This option is intended to ease and make more robust the use of 53 | Python in test or build scripts, for instance. 54 | 55 | 56 | Reference Implementation 57 | ======================== 58 | 59 | A patch implementing this is available from SourceForge:: 60 | 61 | http://sourceforge.net/tracker/download.php?group_id=5470&atid=305470&file_id=6916&aid=429614 62 | 63 | with the patch discussion at:: 64 | 65 | http://sourceforge.net/tracker/?func=detail&atid=305470&aid=429614&group_id=5470 66 | 67 | 68 | Copyright 69 | ========= 70 | 71 | This document has been placed in the public domain. 72 | -------------------------------------------------------------------------------- /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 | Created: 19-Jun-2002 7 | Python-Version: 2.5 8 | Post-History: 9 | 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP proposes that symbols matching the type name should be added 16 | to the types module for all basic Python types in the types module:: 17 | 18 | types.IntegerType -> types.int 19 | types.FunctionType -> types.function 20 | types.TracebackType -> types.traceback 21 | ... 22 | 23 | The long capitalized names currently in the types module will be 24 | deprecated. 25 | 26 | With this change the types module can serve as a replacement for the 27 | new module. The new module shall be deprecated and listed in :pep:`4`. 28 | 29 | 30 | Pronouncement 31 | ============= 32 | 33 | A centralized repository of type names was a mistake. Neither the 34 | "types" nor "new" modules should be carried forward to Python 3.0. 35 | 36 | In the meantime, it does not make sense to make the proposed updates 37 | to the modules. This would cause disruption without any compensating 38 | benefit. 39 | 40 | Instead, the problem that some internal types (frames, functions, 41 | etc.) don't live anywhere outside those modules may be addressed by 42 | either adding them to ``__builtin__`` or sys. This will provide a 43 | smoother transition to Python 3.0. 44 | 45 | 46 | Rationale 47 | ========= 48 | 49 | Using two sets of names for the same objects is redundant and 50 | confusing. 51 | 52 | In Python versions prior to 2.2 the symbols matching many type names 53 | were taken by the factory functions for those types. Now all basic 54 | types have been unified with their factory functions and therefore the 55 | type names are available to be consistently used to refer to the type 56 | object. 57 | 58 | Most types are accessible as either builtins or in the new module but 59 | some types such as traceback and generator are only accessible through 60 | the types module under names which do not match the type name. This 61 | PEP provides a uniform way to access all basic types under a single 62 | set of names. 63 | 64 | 65 | Specification 66 | ============= 67 | 68 | The types module shall pass the following test:: 69 | 70 | import types 71 | for t in vars(types).values(): 72 | if type(t) is type: 73 | assert getattr(types, t.__name__) is t 74 | 75 | The types 'class', 'instance method' and 'dict-proxy' have already 76 | been renamed to the valid Python identifiers 'classobj', 77 | 'instancemethod' and 'dictproxy', making this possible. 78 | 79 | 80 | Backward compatibility 81 | ====================== 82 | 83 | Because of their widespread use it is not planned to actually remove 84 | the long names from the types module in some future version. However, 85 | the long names should be changed in documentation and library sources 86 | to discourage their use in new code. 87 | 88 | 89 | Reference Implementation 90 | ======================== 91 | 92 | A reference implementation is available in 93 | `issue #569328 `_. 94 | 95 | 96 | Copyright 97 | ========= 98 | 99 | This document has been placed in the public domain. 100 | -------------------------------------------------------------------------------- /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 | Created: 22-Jul-2002 7 | Python-Version: 3.0 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP describes an interpretation of multiline string constants 15 | for Python. It suggests stripping spaces after newlines and 16 | stripping a newline if it is first character after an opening 17 | quotation. 18 | 19 | 20 | Rationale 21 | ========= 22 | 23 | This PEP proposes an interpretation of multiline string constants 24 | in Python. Currently, the value of string constant is all the 25 | text between quotations, maybe with escape sequences substituted, 26 | e.g.:: 27 | 28 | def f(): 29 | """ 30 | la-la-la 31 | limona, banana 32 | """ 33 | 34 | def g(): 35 | return "This is \ 36 | string" 37 | 38 | print repr(f.__doc__) 39 | print repr(g()) 40 | 41 | prints:: 42 | 43 | '\n\tla-la-la\n\tlimona, banana\n\t' 44 | 'This is \tstring' 45 | 46 | This PEP suggest two things: 47 | 48 | - ignore the first character after opening quotation, if it is 49 | newline 50 | 51 | - ignore in string constants all spaces and tabs up to 52 | first non-whitespace character, but no more than current 53 | indentation. 54 | 55 | After applying this, previous program will print:: 56 | 57 | 'la-la-la\nlimona, banana\n' 58 | 'This is string' 59 | 60 | To get this result, previous programs could be rewritten for 61 | current Python as (note, this gives the same result with new 62 | strings meaning):: 63 | 64 | def f(): 65 | """\ 66 | la-la-la 67 | limona, banana 68 | """ 69 | 70 | def g(): 71 | "This is \ 72 | string" 73 | 74 | Or stripping can be done with library routines at runtime (as 75 | pydoc does), but this decreases program readability. 76 | 77 | 78 | Implementation 79 | ============== 80 | 81 | I'll say nothing about CPython, Jython or Python.NET. 82 | 83 | In original Python, there is no info about the current indentation 84 | (in spaces) at compile time, so space and tab stripping should be 85 | done at parse time. Currently no flags can be passed to the 86 | parser in program text (like ``from __future__ import xxx``). I 87 | suggest enabling or disabling of this feature at Python compile 88 | time depending of CPP flag ``Py_PARSE_MULTILINE_STRINGS``. 89 | 90 | 91 | Alternatives 92 | ============ 93 | 94 | New interpretation of string constants can be implemented with flags 95 | 'i' and 'o' to string constants, like:: 96 | 97 | i""" 98 | SELECT * FROM car 99 | WHERE model = 'i525' 100 | """ is in new style, 101 | 102 | o"""SELECT * FROM employee 103 | WHERE birth < 1982 104 | """ is in old style, and 105 | 106 | """ 107 | SELECT employee.name, car.name, car.price FROM employee, car 108 | WHERE employee.salary * 36 > car.price 109 | """ is in new style after Python-x.y.z and in old style otherwise. 110 | 111 | Also this feature can be disabled if string is raw, i.e. if flag 'r' 112 | specified. 113 | 114 | 115 | Copyright 116 | ========= 117 | 118 | This document has been placed in the Public Domain. 119 | -------------------------------------------------------------------------------- /peps/pep-0299.rst: -------------------------------------------------------------------------------- 1 | PEP: 299 2 | Title: Special __main__() function in modules 3 | Author: Jeff Epler 4 | Status: Rejected 5 | Type: Standards Track 6 | Created: 12-Aug-2002 7 | Python-Version: 2.3 8 | Post-History: 29-Mar-2006 9 | 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | Many Python modules are also intended to be callable as standalone 16 | scripts. This PEP proposes that a special function called ``__main__()`` 17 | should serve this purpose. 18 | 19 | 20 | Motivation 21 | ========== 22 | 23 | There should be one simple and universal idiom for invoking a module 24 | as a standalone script. 25 | 26 | The semi-standard idiom:: 27 | 28 | if __name__ == '__main__': 29 | perform "standalone" functionality 30 | 31 | is unclear to programmers of languages like C and C++. It also does 32 | not permit invocation of the standalone function when the module is 33 | imported. The variant:: 34 | 35 | if __name__ == '__main__': 36 | main_function() 37 | 38 | is sometimes seen, but there exists no standard name for the function, 39 | and because arguments are taken from sys.argv it is not possible to 40 | pass specific arguments without changing the argument list seen by all 41 | other modules. (Imagine a threaded Python program, with two threads 42 | wishing to invoke the standalone functionality of different modules 43 | with different argument lists) 44 | 45 | 46 | Proposal 47 | ======== 48 | 49 | The standard name of the 'main function' should be ``__main__``. When a 50 | module is invoked on the command line, such as:: 51 | 52 | python mymodule.py 53 | 54 | then the module behaves as though the following lines existed at the 55 | end of the module (except that the attribute __sys may not be used or 56 | assumed to exist elsewhere in the script):: 57 | 58 | if globals().has_key("__main__"): 59 | import sys as __sys 60 | __sys.exit(__main__(__sys.argv)) 61 | 62 | Other modules may execute:: 63 | 64 | import mymodule mymodule.__main__(['mymodule', ...]) 65 | 66 | It is up to ``mymodule`` to document thread-safety issues or other 67 | issues which might restrict use of ``__main__``. (Other issues might 68 | include use of mutually exclusive GUI modules, non-sharable resources 69 | like hardware devices, reassignment of ``sys.stdin``/``stdout``, etc) 70 | 71 | 72 | Implementation 73 | ============== 74 | 75 | In ``modules/main.c``, the block near line 385 (after the 76 | ``PyRun_AnyFileExFlags`` call) will be changed so that the above code 77 | (or its C equivalent) is executed. 78 | 79 | 80 | Open Issues 81 | =========== 82 | 83 | * Should the return value from ``__main__`` be treated as the exit value? 84 | 85 | Yes. Many ``__main__`` will naturally return ``None``, which 86 | ``sys.exit`` translates into a "success" return code. In those that 87 | return a numeric result, it behaves just like the argument to 88 | ``sys.exit()`` or the return value from C's main(). 89 | 90 | * Should the argument list to ``__main__`` include ``argv[0]``, or just the 91 | "real" arguments ``argv[1:]``? 92 | 93 | ``argv[0]`` is included for symmetry with ``sys.argv`` and easy 94 | transition to the new standard idiom. 95 | 96 | 97 | Rejection 98 | ========= 99 | 100 | In a short discussion on python-dev [1]_, two major backwards 101 | compatibility problems were brought up and Guido pronounced that he 102 | doesn't like the idea anyway as it's "not worth the change (in docs, 103 | user habits, etc.) and there's nothing particularly broken." 104 | 105 | 106 | References 107 | ========== 108 | 109 | .. [1] Georg Brandl, "What about PEP 299", 110 | https://mail.python.org/pipermail/python-dev/2006-March/062951.html 111 | 112 | 113 | Copyright 114 | ========= 115 | 116 | This document has been placed in the public domain. 117 | -------------------------------------------------------------------------------- /peps/pep-0306.rst: -------------------------------------------------------------------------------- 1 | PEP: 306 2 | Title: How to Change Python's Grammar 3 | Author: Michael Hudson , Jack Diederich , Alyssa Coghlan , Benjamin Peterson 4 | Status: Withdrawn 5 | Type: Informational 6 | Created: 29-Jan-2003 7 | Post-History: 30-Jan-2003 8 | 9 | 10 | Note 11 | ==== 12 | 13 | This PEP has been moved to the Python dev guide [1]_. 14 | 15 | 16 | Abstract 17 | ======== 18 | 19 | There's more to changing Python's grammar than editing 20 | ``Grammar/Grammar`` and ``Python/compile.c``. This PEP aims to be a 21 | checklist of places that must also be fixed. 22 | 23 | It is probably incomplete. If you see omissions, just add them if 24 | you can -- you are not going to offend the author's sense of 25 | ownership. Otherwise submit a bug or patch and assign it to mwh. 26 | 27 | This PEP is not intended to be an instruction manual on Python 28 | grammar hacking, for several reasons. 29 | 30 | 31 | Rationale 32 | ========= 33 | 34 | People are getting this wrong all the time; it took well over a 35 | year before someone noticed [2]_ that adding the floor division 36 | operator (``//``) broke the ``parser`` module. 37 | 38 | 39 | Checklist 40 | ========= 41 | 42 | - ``Grammar/Grammar``: OK, you'd probably worked this one out :) 43 | 44 | - ``Parser/Python.asdl`` may need changes to match the ``Grammar``. Run 45 | ``make`` to regenerate ``Include/Python-ast.h`` and 46 | ``Python/Python-ast.c``. 47 | 48 | - ``Python/ast.c`` will need changes to create the AST objects 49 | involved with the ``Grammar`` change. ``Lib/compiler/ast.py`` will 50 | need matching changes to the pure-python AST objects. 51 | 52 | - ``Parser/pgen`` needs to be rerun to regenerate ``Include/graminit.h`` 53 | and ``Python/graminit.c``. (make should handle this for you.) 54 | 55 | - ``Python/symbtable.c``: This handles the symbol collection pass 56 | that happens immediately before the compilation pass. 57 | 58 | - ``Python/compile.c``: You will need to create or modify the 59 | ``compiler_*`` functions to generate opcodes for your productions. 60 | 61 | - You may need to regenerate ``Lib/symbol.py`` and/or ``Lib/token.py`` 62 | and/or ``Lib/keyword.py``. 63 | 64 | - The ``parser`` module. Add some of your new syntax to ``test_parser``, 65 | bang on ``Modules/parsermodule.c`` until it passes. 66 | 67 | - Add some usage of your new syntax to ``test_grammar.py``. 68 | 69 | - The ``compiler`` package. A good test is to compile the standard 70 | library and test suite with the ``compiler`` package and then check 71 | it runs. Note that this only needs to be done in Python 2.x. 72 | 73 | - If you've gone so far as to change the token structure of 74 | Python, then the ``Lib/tokenizer.py`` library module will need to 75 | be changed. 76 | 77 | - Certain changes may require tweaks to the library module 78 | ``pyclbr``. 79 | 80 | - Documentation must be written! 81 | 82 | - After everything's been checked in, you're likely to see a new 83 | change to ``Python/Python-ast.c``. This is because this 84 | (generated) file contains the SVN version of the source from 85 | which it was generated. There's no way to avoid this; you just 86 | have to submit this file separately. 87 | 88 | 89 | References 90 | ========== 91 | 92 | .. [1] CPython Developer's Guide: Changing CPython's Grammar 93 | https://devguide.python.org/grammar/ 94 | 95 | .. [2] SF Bug #676521, parser module validation failure 96 | https://bugs.python.org/issue676521 97 | 98 | 99 | Copyright 100 | ========= 101 | 102 | This document has been placed in the public domain. 103 | -------------------------------------------------------------------------------- /peps/pep-0332.rst: -------------------------------------------------------------------------------- 1 | PEP: 332 2 | Title: Byte vectors and String/Unicode Unification 3 | Author: Skip Montanaro 4 | Status: Rejected 5 | Type: Standards Track 6 | Created: 11-Aug-2004 7 | Python-Version: 2.5 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP outlines the introduction of a raw ``bytes`` sequence object 15 | and the unification of the current ``str`` and ``unicode`` objects. 16 | 17 | 18 | Rejection Notice 19 | ================ 20 | 21 | This PEP is rejected in this form. The author has expressed lack of 22 | time to continue to shepherd it, and discussion on python-dev has 23 | moved to a slightly different proposal which will (eventually) be 24 | written up as a new PEP. See the thread starting at 25 | https://mail.python.org/pipermail/python-dev/2006-February/060930.html. 26 | 27 | 28 | Rationale 29 | ========= 30 | 31 | Python's current string objects are overloaded. They serve both to 32 | hold ASCII and non-ASCII character data and to also hold sequences of 33 | raw bytes which have no reasonable interpretation as displayable 34 | character sequences. This overlap hasn't been a big problem in the 35 | past, but as Python moves closer to requiring source code to be 36 | properly encoded, the use of strings to represent raw byte sequences 37 | will be more problematic. In addition, as Python's Unicode support 38 | has improved, it's easier to consider strings as ASCII-encoded Unicode 39 | objects. 40 | 41 | 42 | Proposed Implementation 43 | ======================= 44 | 45 | The number in parentheses indicates the Python version in which the 46 | feature will be introduced. 47 | 48 | - Add a ``bytes`` builtin which is just a synonym for ``str``. (2.5) 49 | 50 | - Add a ``b"..."`` string literal which is equivalent to raw string 51 | literals, with the exception that values which conflict with the 52 | source encoding of the containing file not generate warnings. (2.5) 53 | 54 | - Warn about the use of variables named "bytes". (2.5 or 2.6) 55 | 56 | - Introduce a ``bytes`` builtin which refers to a sequence distinct 57 | from the ``str`` type. (2.6) 58 | 59 | - Make ``str`` a synonym for ``unicode``. (3.0) 60 | 61 | 62 | Bytes Object API 63 | ================ 64 | 65 | TBD. 66 | 67 | 68 | Issues 69 | ====== 70 | 71 | - Can this be accomplished before Python 3.0? 72 | 73 | - Should ``bytes`` objects be mutable or immutable? (Guido seems to 74 | like them to be mutable.) 75 | 76 | 77 | Copyright 78 | ========= 79 | 80 | This document has been placed in the public domain. 81 | -------------------------------------------------------------------------------- /peps/pep-0336.rst: -------------------------------------------------------------------------------- 1 | PEP: 336 2 | Title: Make None Callable 3 | Author: Andrew McClelland 4 | Status: Rejected 5 | Type: Standards Track 6 | Created: 28-Oct-2004 7 | Post-History: 8 | 9 | 10 | Abstract 11 | ======== 12 | 13 | ``None`` should be a callable object that when called with any 14 | arguments has no side effect and returns ``None``. 15 | 16 | 17 | BDFL Pronouncement 18 | ================== 19 | 20 | This PEP is rejected. It is considered a feature that ``None`` raises 21 | an error when called. The proposal falls short in tests for 22 | obviousness, clarity, explicitness, and necessity. The provided Switch 23 | example is nice but easily handled by a simple lambda definition. 24 | See python-dev discussion on 17 June 2005 [1]_. 25 | 26 | 27 | Motivation 28 | ========== 29 | 30 | To allow a programming style for selectable actions that is more 31 | in accordance with the minimalistic functional programming goals 32 | of the Python language. 33 | 34 | 35 | Rationale 36 | ========= 37 | 38 | Allow the use of ``None`` in method tables as a universal no effect 39 | rather than either (1) checking a method table entry against ``None`` 40 | before calling, or (2) writing a local no effect method with 41 | arguments similar to other functions in the table. 42 | 43 | The semantics would be effectively:: 44 | 45 | class None: 46 | 47 | def __call__(self, *args): 48 | pass 49 | 50 | 51 | How To Use 52 | ========== 53 | 54 | Before, checking function table entry against ``None``:: 55 | 56 | class Select: 57 | 58 | def a(self, input): 59 | print 'a' 60 | 61 | def b(self, input): 62 | print 'b' 63 | 64 | def c(self, input): 65 | print 'c' 66 | 67 | def __call__(self, input): 68 | function = { 1 : self.a, 69 | 2 : self.b, 70 | 3 : self.c 71 | }.get(input, None) 72 | if function: return function(input) 73 | 74 | Before, using a local no effect method:: 75 | 76 | class Select: 77 | 78 | def a(self, input): 79 | print 'a' 80 | 81 | def b(self, input): 82 | print 'b' 83 | 84 | def c(self, input): 85 | print 'c' 86 | 87 | def nop(self, input): 88 | pass 89 | 90 | def __call__(self, input): 91 | return { 1 : self.a, 92 | 2 : self.b, 93 | 3 : self.c 94 | }.get(input, self.nop)(input) 95 | 96 | After:: 97 | 98 | class Select: 99 | 100 | def a(self, input): 101 | print 'a' 102 | 103 | def b(self, input): 104 | print 'b' 105 | 106 | def c(self, input): 107 | print 'c' 108 | 109 | def __call__(self, input): 110 | return { 1 : self.a, 111 | 2 : self.b, 112 | 3 : self.c 113 | }.get(input, None)(input) 114 | 115 | 116 | References 117 | ========== 118 | 119 | .. [1] Raymond Hettinger, Propose to reject PEP 336 -- Make None Callable 120 | https://mail.python.org/pipermail/python-dev/2005-June/054280.html 121 | 122 | 123 | Copyright 124 | ========= 125 | 126 | This document has been placed in the public domain. 127 | -------------------------------------------------------------------------------- /peps/pep-0341.rst: -------------------------------------------------------------------------------- 1 | PEP: 341 2 | Title: Unifying try-except and try-finally 3 | Author: Georg Brandl 4 | Status: Final 5 | Type: Standards Track 6 | Created: 04-May-2005 7 | Python-Version: 2.5 8 | Post-History: 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP proposes a change in the syntax and semantics of try 15 | statements to allow combined try-except-finally blocks. This 16 | means in short that it would be valid to write:: 17 | 18 | try: 19 | 20 | except Exception: 21 | 22 | finally: 23 | 24 | 25 | 26 | Rationale/Proposal 27 | ================== 28 | 29 | There are many use cases for the try-except statement and 30 | for the try-finally statement per se; however, often one needs 31 | to catch exceptions and execute some cleanup code afterwards. 32 | It is slightly annoying and not very intelligible that 33 | one has to write:: 34 | 35 | f = None 36 | try: 37 | try: 38 | f = open(filename) 39 | text = f.read() 40 | except IOError: 41 | print 'An error occurred' 42 | finally: 43 | if f: 44 | f.close() 45 | 46 | So it is proposed that a construction like this:: 47 | 48 | try: 49 | 50 | except Ex1: 51 | 52 | 53 | else: 54 | 55 | finally: 56 | 57 | 58 | be exactly the same as the legacy:: 59 | 60 | try: 61 | try: 62 | 63 | except Ex1: 64 | 65 | 66 | else: 67 | 68 | finally: 69 | 70 | 71 | This is backwards compatible, and every try statement that is 72 | legal today would continue to work. 73 | 74 | 75 | Changes to the grammar 76 | ====================== 77 | 78 | The grammar for the try statement, which is currently:: 79 | 80 | try_stmt: ('try' ':' suite (except_clause ':' suite)+ 81 | ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) 82 | 83 | would have to become:: 84 | 85 | try_stmt: 'try' ':' suite 86 | ( 87 | (except_clause ':' suite)+ 88 | ['else' ':' suite] 89 | ['finally' ':' suite] 90 | | 91 | 'finally' ':' suite 92 | ) 93 | 94 | 95 | Implementation 96 | ============== 97 | 98 | As the PEP author currently does not have sufficient knowledge 99 | of the CPython implementation, he is unfortunately not able 100 | to deliver one. Thomas Lee has submitted a patch [2]_. 101 | 102 | However, according to Guido, it should be a piece of cake to 103 | implement [1]_ -- at least for a core hacker. 104 | 105 | This patch was committed 17 December 2005, SVN revision 41740 [3]_. 106 | 107 | 108 | References 109 | ========== 110 | 111 | .. [1] https://mail.python.org/pipermail/python-dev/2005-May/053319.html 112 | .. [2] https://bugs.python.org/issue1355913 113 | .. [3] https://mail.python.org/pipermail/python-checkins/2005-December/048457.html 114 | 115 | 116 | Copyright 117 | ========= 118 | 119 | This document has been placed in the public domain. 120 | -------------------------------------------------------------------------------- /peps/pep-0375.rst: -------------------------------------------------------------------------------- 1 | PEP: 375 2 | Title: Python 3.1 Release Schedule 3 | Author: Benjamin Peterson 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Created: 08-Feb-2009 8 | Python-Version: 3.1 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for Python 3.1. 15 | The schedule primarily concerns itself with PEP-sized items. Small features may 16 | be added up to and including the first beta release. Bugs may be fixed until 17 | the final release. 18 | 19 | 20 | Release Manager and Crew 21 | ======================== 22 | 23 | =================== ================== 24 | Position Name 25 | =================== ================== 26 | 3.1 Release Manager Benjamin Peterson 27 | Windows installers Martin v. Loewis 28 | Mac installers Ronald Oussoren 29 | =================== ================== 30 | 31 | 32 | Release Schedule 33 | ================ 34 | 35 | - 3.1a1 March 7, 2009 36 | - 3.1a2 April 4, 2009 37 | - 3.1b1 May 6, 2009 38 | - 3.1rc1 May 30, 2009 39 | - 3.1rc2 June 13, 2009 40 | - 3.1 final June 27, 2009 41 | 42 | Maintenance Releases 43 | ==================== 44 | 45 | 3.1 is no longer maintained. 3.1 received security fixes until June 46 | 2012. 47 | 48 | Previous maintenance releases are: 49 | 50 | - v3.1.1rc1 2009-08-13 51 | - v3.1.1 2009-08-16 52 | - v3.1.2rc1 2010-03-06 53 | - v3.1.2 2010-03-20 54 | - v3.1.3rc1 2010-11-13 55 | - v3.1.3 2010-11-27 56 | - v3.1.4rc1 2011-05-29 57 | - v3.1.4 2011-06-11 58 | - v3.1.5rc1 2012-02-23 59 | - v3.1.5rc2 2012-03-15 60 | - v3.1.5 2012-04-06 61 | 62 | Features for 3.1 63 | ================ 64 | 65 | - importlib 66 | - io in C 67 | - Update simplejson to the latest external version [#simplejson]_. 68 | - Ordered dictionary for collections (:pep:`372`). 69 | - auto-numbered replacement fields in str.format() strings [#strformat]_ 70 | - Nested with-statements in one with statement 71 | 72 | 73 | Footnotes 74 | ========= 75 | 76 | .. [#simplejson] 77 | http://bugs.python.org/issue4136 78 | 79 | .. [#strformat] 80 | http://bugs.python.org/issue5237 81 | 82 | 83 | 84 | Copyright 85 | ========= 86 | 87 | This document has been placed in the public domain. 88 | -------------------------------------------------------------------------------- /peps/pep-0392.rst: -------------------------------------------------------------------------------- 1 | PEP: 392 2 | Title: Python 3.2 Release Schedule 3 | Author: Georg Brandl 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Created: 30-Dec-2009 8 | Python-Version: 3.2 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for the 15 | Python 3.2 series. The schedule primarily concerns itself with PEP-sized 16 | items. 17 | 18 | .. Small features may be added up to and including the first beta 19 | release. Bugs may be fixed until the final release, which is planned 20 | for February 2011. 21 | 22 | 23 | Release Manager and Crew 24 | ======================== 25 | 26 | - 3.2 Release Manager: Georg Brandl 27 | - Windows installers: Martin v. Loewis 28 | - Mac installers: Ronald Oussoren 29 | - Documentation: Georg Brandl 30 | 31 | 32 | 3.2 Lifespan 33 | ============ 34 | 35 | 3.2 will receive bugfix updates approximately every 4-6 months for 36 | approximately 18 months. After the release of 3.3.0 final (see PEP 37 | 398), a final 3.2 bugfix update will be released. After that, 38 | security updates (source only) will be released until 5 years after 39 | the release of 3.2 final, which was planned for February 2016. 40 | 41 | As of 2016-02-20, Python 3.2.x reached end-of-life status. The final 42 | source release was 3.2.6 in October 2014. 43 | 44 | 45 | Release Schedule 46 | ================ 47 | 48 | 3.2 schedule 49 | ------------ 50 | 51 | - 3.2 alpha 1: August 1, 2010 52 | - 3.2 alpha 2: September 6, 2010 53 | - 3.2 alpha 3: October 12, 2010 54 | - 3.2 alpha 4: November 16, 2010 55 | - 3.2 beta 1: December 6, 2010 56 | 57 | (No new features beyond this point.) 58 | 59 | - 3.2 beta 2: December 20, 2010 60 | - 3.2 candidate 1: January 16, 2011 61 | - 3.2 candidate 2: January 31, 2011 62 | - 3.2 candidate 3: February 14, 2011 63 | - 3.2 final: February 20, 2011 64 | 65 | .. don't forget to update final date above as well 66 | 67 | 3.2.1 schedule 68 | -------------- 69 | 70 | - 3.2.1 beta 1: May 8, 2011 71 | - 3.2.1 candidate 1: May 17, 2011 72 | - 3.2.1 candidate 2: July 3, 2011 73 | - 3.2.1 final: July 11, 2011 74 | 75 | 3.2.2 schedule 76 | -------------- 77 | 78 | - 3.2.2 candidate 1: August 14, 2011 79 | - 3.2.2 final: September 4, 2011 80 | 81 | 3.2.3 schedule 82 | -------------- 83 | 84 | - 3.2.3 candidate 1: February 25, 2012 85 | - 3.2.3 candidate 2: March 18, 2012 86 | - 3.2.3 final: April 11, 2012 87 | 88 | 3.2.4 schedule 89 | -------------- 90 | 91 | - 3.2.4 candidate 1: March 23, 2013 92 | - 3.2.4 final: April 6, 2013 93 | 94 | 3.2.5 schedule (regression fix release) 95 | --------------------------------------- 96 | 97 | - 3.2.5 final: May 13, 2013 98 | 99 | -- Only security releases after 3.2.5 -- 100 | 101 | 3.2.6 schedule 102 | -------------- 103 | 104 | - 3.2.6 candidate 1 (source-only release): October 4, 2014 105 | - 3.2.6 final (source-only release): October 11, 2014 106 | 107 | 108 | Features for 3.2 109 | ================ 110 | 111 | Note that :pep:`3003` is in effect: no changes to language 112 | syntax and no additions to the builtins may be made. 113 | 114 | No large-scale changes have been recorded yet. 115 | 116 | 117 | Copyright 118 | ========= 119 | 120 | This document has been placed in the public domain. 121 | -------------------------------------------------------------------------------- /peps/pep-0415.rst: -------------------------------------------------------------------------------- 1 | PEP: 415 2 | Title: Implement context suppression with exception attributes 3 | Author: Benjamin Peterson 4 | BDFL-Delegate: Alyssa Coghlan 5 | Status: Final 6 | Type: Standards Track 7 | Created: 26-Feb-2012 8 | Python-Version: 3.3 9 | Post-History: 26-Feb-2012 10 | Replaces: 409 11 | Resolution: https://mail.python.org/pipermail/python-dev/2012-May/119467.html 12 | 13 | 14 | Abstract 15 | ======== 16 | 17 | :pep:`409` introduced support for the ``raise exc from None`` construct to 18 | allow the display of the exception context to be explicitly suppressed. 19 | This PEP retains the language level changes already implemented in :pep:`409`, 20 | but replaces the underlying implementation mechanism with a simpler approach 21 | based on a new ``__suppress_context__`` attribute on all ``BaseException`` 22 | instances. 23 | 24 | 25 | PEP Acceptance 26 | ============== 27 | 28 | This PEP was accepted by Alyssa Coghlan on the 14th of May, 2012. 29 | 30 | 31 | Rationale 32 | ========= 33 | 34 | :pep:`409` changes ``__cause__`` to be ``Ellipsis`` by default. Then if 35 | ``__cause__`` is set to ``None`` by ``raise exc from None``, no context or cause 36 | will be printed should the exception be uncaught. 37 | 38 | The main problem with this scheme is it complicates the role of 39 | ``__cause__``. ``__cause__`` should indicate the cause of the exception not 40 | whether ``__context__`` should be printed or not. This use of ``__cause__`` is 41 | also not easily extended in the future. For example, we may someday want to 42 | allow the programmer to select which of ``__context__`` and ``__cause__`` will 43 | be printed. The :pep:`409` implementation is not amenable to this. 44 | 45 | The use of ``Ellipsis`` is a hack. Before :pep:`409`, ``Ellipsis`` was used 46 | exclusively in extended slicing. Extended slicing has nothing to do with 47 | exceptions, so it's not clear to someone inspecting an exception object why 48 | ``__cause__`` should be set to ``Ellipsis``. Using ``Ellipsis`` by default for 49 | ``__cause__`` makes it asymmetrical with ``__context__``. 50 | 51 | 52 | Proposal 53 | ======== 54 | 55 | A new attribute on ``BaseException``, ``__suppress_context__``, will 56 | be introduced. Whenever ``__cause__`` is set, ``__suppress_context__`` 57 | will be set to ``True``. In particular, ``raise exc from cause`` 58 | syntax will set ``exc.__suppress_context__`` to ``True``. Exception 59 | printing code will check for that attribute to determine whether 60 | context and cause will be printed. ``__cause__`` will return to its 61 | original purpose and values. 62 | 63 | There is precedence for ``__suppress_context__`` with the 64 | ``print_line_and_file`` exception attribute. 65 | 66 | To summarize, ``raise exc from cause`` will be equivalent to:: 67 | 68 | exc.__cause__ = cause 69 | raise exc 70 | 71 | where ``exc.__cause__ = cause`` implicitly sets 72 | ``exc.__suppress_context__``. 73 | 74 | 75 | Patches 76 | ======= 77 | 78 | There is a patch on `Issue 14133`_. 79 | 80 | 81 | References 82 | ========== 83 | 84 | .. _issue 14133: 85 | http://bugs.python.org/issue14133 86 | 87 | 88 | Copyright 89 | ========= 90 | 91 | This document has been placed in the public domain. 92 | -------------------------------------------------------------------------------- /peps/pep-0417.rst: -------------------------------------------------------------------------------- 1 | PEP: 417 2 | Title: Including mock in the Standard Library 3 | Author: Michael Foord 4 | Status: Final 5 | Type: Standards Track 6 | Created: 12-Mar-2012 7 | Python-Version: 3.3 8 | Post-History: 12-Mar-2012 9 | Resolution: https://mail.python.org/pipermail/python-dev/2012-March/117507.html 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP proposes adding the mock [1]_ testing library 16 | to the Python standard library as ``unittest.mock``. 17 | 18 | 19 | Rationale 20 | ========= 21 | 22 | Creating mock objects for testing is a common need in Python. 23 | Many developers create ad-hoc mocks, as needed, in their test 24 | suites. This is currently what we do in the Python test suite, 25 | where a standardised mock object library would be helpful. 26 | 27 | There are many mock object libraries available for Python [2]_. 28 | Of these, mock is overwhelmingly the most popular, with as many 29 | downloads on PyPI as the other mocking libraries combined. 30 | 31 | An advantage of mock is that it is a mocking library and not a 32 | framework. It provides a configurable and flexible mock object, 33 | without being opinionated about how you write your tests. The 34 | mock api is now well battle-tested and stable. 35 | 36 | mock also handles safely monkeypatching and unmonkeypatching 37 | objects during the scope of a test. This is hard to do safely 38 | and many developers / projects mimic this functionality 39 | (often incorrectly). A standardised way to do this, handling 40 | the complexity of patching in the presence of the descriptor 41 | protocol (etc) is useful. People are asking for a "patch" [3]_ 42 | feature to unittest. Doing this via mock.patch is preferable 43 | to re-implementing part of this functionality in unittest. 44 | 45 | 46 | Background 47 | ========== 48 | 49 | Addition of mock to the Python standard library was discussed 50 | and agreed to at the Python Language Summit 2012. 51 | 52 | 53 | Open Issues 54 | =========== 55 | 56 | As of release 0.8, which is current at the time of writing, 57 | mock is compatible with Python 2.4-3.2. Moving into the Python 58 | standard library will allow for the removal of some Python 2 59 | specific "compatibility hacks". 60 | 61 | mock 0.8 introduced a new feature, "auto-speccing", obsoletes 62 | an older mock feature called "mocksignature". The 63 | "mocksignature" functionality can be removed from mock 64 | altogether prior to inclusion. 65 | 66 | 67 | References 68 | ========== 69 | 70 | .. [1] `mock library on PyPI `_ 71 | .. [2] http://pypi.python.org/pypi?%3Aaction=search&term=mock&submit=search 72 | .. [3] http://bugs.python.org/issue11664 73 | 74 | 75 | Copyright 76 | ========= 77 | 78 | This document has been placed in the public domain. 79 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /peps/pep-0424.rst: -------------------------------------------------------------------------------- 1 | PEP: 424 2 | Title: A method for exposing a length hint 3 | Author: Alex Gaynor 4 | Status: Final 5 | Type: Standards Track 6 | Created: 14-Jul-2012 7 | Python-Version: 3.4 8 | Post-History: `15-Jul-2012 `__ 9 | 10 | Abstract 11 | ======== 12 | 13 | CPython currently defines a ``__length_hint__`` method on several 14 | types, such as various iterators. This method is then used by various 15 | other functions (such as ``list``) to presize lists based on the 16 | estimate returned by ``__length_hint__``. Types which are not sized, 17 | and thus should not define ``__len__``, can then define 18 | ``__length_hint__``, to allow estimating or computing a size (such as 19 | many iterators). 20 | 21 | Specification 22 | ============= 23 | 24 | This PEP formally documents ``__length_hint__`` for other interpreters 25 | and non-standard-library Python modules to implement. 26 | 27 | ``__length_hint__`` must return an integer (else a ``TypeError`` is 28 | raised) or ``NotImplemented``, and is not required to be accurate. It 29 | may return a value that is either larger or smaller than the actual 30 | size of the container. A return value of ``NotImplemented`` indicates 31 | that there is no finite length estimate. It may not return a negative 32 | value (else a ValueError is raised). 33 | 34 | In addition, a new function ``operator.length_hint`` hint is added, 35 | with the following semantics (which define how ``__length_hint__`` 36 | should be used):: 37 | 38 | def length_hint(obj, default=0): 39 | """Return an estimate of the number of items in obj. 40 | 41 | This is useful for presizing containers when building from an 42 | iterable. 43 | 44 | If the object supports len(), the result will be 45 | exact. Otherwise, it may over- or under-estimate by an 46 | arbitrary amount. The result will be an integer >= 0. 47 | """ 48 | try: 49 | return len(obj) 50 | except TypeError: 51 | try: 52 | get_hint = type(obj).__length_hint__ 53 | except AttributeError: 54 | return default 55 | try: 56 | hint = get_hint(obj) 57 | except TypeError: 58 | return default 59 | if hint is NotImplemented: 60 | return default 61 | if not isinstance(hint, int): 62 | raise TypeError("Length hint must be an integer, not %r" % 63 | type(hint)) 64 | if hint < 0: 65 | raise ValueError("__length_hint__() should return >= 0") 66 | return hint 67 | 68 | 69 | Rationale 70 | ========= 71 | 72 | Being able to pre-allocate lists based on the expected size, as 73 | estimated by ``__length_hint__``, can be a significant optimization. 74 | CPython has been observed to run some code faster than PyPy, purely 75 | because of this optimization being present. 76 | 77 | Copyright 78 | ========= 79 | 80 | This document has been placed into the public domain. 81 | -------------------------------------------------------------------------------- /peps/pep-0429.rst: -------------------------------------------------------------------------------- 1 | PEP: 429 2 | Title: Python 3.4 Release Schedule 3 | Author: Larry Hastings 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Created: 17-Oct-2012 8 | Python-Version: 3.4 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.4. 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 March 2014. 21 | 22 | 23 | Release Manager and Crew 24 | ======================== 25 | 26 | - 3.4 Release Manager: Larry Hastings 27 | - Windows installers: Martin v. Löwis 28 | - Mac installers: Ned Deily 29 | - Documentation: Georg Brandl 30 | 31 | 32 | Release Schedule 33 | ================ 34 | 35 | Python 3.4 has now reached its end-of-life and has been retired. 36 | No more releases will be made. 37 | 38 | These are all the historical releases of Python 3.4, 39 | including their release dates. 40 | 41 | - 3.4.0 alpha 1: August 3, 2013 42 | - 3.4.0 alpha 2: September 9, 2013 43 | - 3.4.0 alpha 3: September 29, 2013 44 | - 3.4.0 alpha 4: October 20, 2013 45 | - 3.4.0 beta 1: November 24, 2013 46 | - 3.4.0 beta 2: January 5, 2014 47 | - 3.4.0 beta 3: January 26, 2014 48 | - 3.4.0 candidate 1: February 10, 2014 49 | - 3.4.0 candidate 2: February 23, 2014 50 | - 3.4.0 candidate 3: March 9, 2014 51 | - 3.4.0 final: March 16, 2014 52 | - 3.4.1 candidate 1: May 5, 2014 53 | - 3.4.1 final: May 18, 2014 54 | - 3.4.2 candidate 1: September 22, 2014 55 | - 3.4.2 final: October 6, 2014 56 | - 3.4.3 candidate 1: February 8, 2015 57 | - 3.4.3 final: February 25, 2015 58 | - 3.4.4 candidate 1: December 6, 2015 59 | - 3.4.4 final: December 20, 2015 60 | - 3.4.5 candidate 1: June 12, 2016 61 | - 3.4.5 final: June 26, 2016 62 | - 3.4.6 candidate 1: January 2, 2017 63 | - 3.4.6 final: January 17, 2017 64 | - 3.4.7 candidate 1: July 25, 2017 65 | - 3.4.7 final: August 9, 2017 66 | - 3.4.8 candidate 1: January 23, 2018 67 | - 3.4.8 final: February 4, 2018 68 | - 3.4.9 candidate 1: July 19, 2018 69 | - 3.4.9 final: August 2, 2018 70 | - 3.4.10 candidate 1: March 4, 2019 71 | - 3.4.10 final: March 18, 2019 72 | 73 | 74 | Features for 3.4 75 | ================ 76 | 77 | Implemented / Final PEPs: 78 | 79 | * :pep:`428`, a "pathlib" module providing object-oriented filesystem paths 80 | * :pep:`435`, a standardized "enum" module 81 | * :pep:`436`, a build enhancement that will help generate introspection information for builtins 82 | * :pep:`442`, improved semantics for object finalization 83 | * :pep:`443`, adding single-dispatch generic functions to the standard library 84 | * :pep:`445`, a new C API for implementing custom memory allocators 85 | * :pep:`446`, changing file descriptors to not be inherited by default in subprocesses 86 | * :pep:`450`, a new "statistics" module 87 | * :pep:`451`, standardizing module metadata for Python's module import system 88 | * :pep:`453`, a bundled installer for the *pip* package manager 89 | * :pep:`454`, a new "tracemalloc" module for tracing Python memory allocations 90 | * :pep:`456`, a new hash algorithm for Python strings and binary data 91 | * :pep:`3154`, a new and improved protocol for pickled objects 92 | * :pep:`3156`, a new "asyncio" module, a new framework for asynchronous I/O 93 | 94 | Deferred to post-3.4: 95 | 96 | * :pep:`431`, improved support for time zone databases 97 | * :pep:`441`, improved Python zip application support 98 | * :pep:`447`, support for __locallookup__ metaclass method 99 | * :pep:`448`, additional unpacking generalizations 100 | * :pep:`455`, key transforming dictionary 101 | 102 | 103 | Copyright 104 | ========= 105 | 106 | This document has been placed in the public domain. 107 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /peps/pep-0458-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0458-1.png -------------------------------------------------------------------------------- /peps/pep-0464.rst: -------------------------------------------------------------------------------- 1 | PEP: 464 2 | Title: Removal of the PyPI Mirror Authenticity API 3 | Author: Donald Stufft 4 | BDFL-Delegate: Richard Jones 5 | Discussions-To: distutils-sig@python.org 6 | Status: Final 7 | Type: Process 8 | Topic: Packaging 9 | Created: 02-Mar-2014 10 | Post-History: 04-Mar-2014 11 | Replaces: 381 12 | Resolution: https://mail.python.org/pipermail/distutils-sig/2014-March/024027.html 13 | 14 | 15 | Abstract 16 | ======== 17 | 18 | This PEP proposes the deprecation and removal of the PyPI Mirror Authenticity 19 | API, this includes the /serverkey URL and all of the URLs under /serversig. 20 | 21 | 22 | Rationale 23 | ========= 24 | 25 | The PyPI mirroring infrastructure (defined in :pep:`381`) provides a means to 26 | mirror the content of PyPI used by the automatic installers, and as a component 27 | of that, it provides a method for verifying the authenticity of the mirrored 28 | content. 29 | 30 | This PEP proposes the removal of this API due to: 31 | 32 | * There are no known implementations that utilize this API, this includes 33 | `pip `_ and 34 | `setuptools `_. 35 | * Because this API uses DSA it is vulnerable to leaking the private key if 36 | there is *any* bias in the random nonce. 37 | * This API solves one small corner of the trust problem, however the problem 38 | itself is much larger and it would be better to have a fully fledged system, 39 | such as :pep:`The Update Framework <458>`, 40 | instead. 41 | 42 | Due to the issues it has and the lack of use it is the opinion of this PEP 43 | that it does not provide any practical benefit to justify the additional 44 | complexity. 45 | 46 | 47 | Plan for Deprecation & Removal 48 | ============================== 49 | 50 | Immediately upon the acceptance of this PEP the Mirror Authenticity API will 51 | be considered deprecated and mirroring agents and installation tools should 52 | stop accessing it. 53 | 54 | Instead of actually removing it from the current code base (PyPI 1.0) the 55 | current work to replace PyPI 1.0 with a new code base (PyPI 2.0) will simply 56 | not implement this API. This would cause the API to be "removed" when the 57 | switch from 1.0 to 2.0 occurs. 58 | 59 | If PyPI 2.0 has not been deployed in place of PyPI 1.0 by Sept 01 2014 then 60 | this PEP will be implemented in the PyPI 1.0 code base instead (by removing 61 | the associated code). 62 | 63 | No changes will be required in the installers, however :pep:`381` compliant 64 | mirroring clients, such as 65 | `bandersnatch `_ and 66 | `pep381client `_ will need to be 67 | updated to no longer attempt to mirror the /serversig URLs. 68 | 69 | 70 | Copyright 71 | ========= 72 | 73 | This document has been placed in the public domain. 74 | -------------------------------------------------------------------------------- /peps/pep-0478.rst: -------------------------------------------------------------------------------- 1 | PEP: 478 2 | Title: Python 3.5 Release Schedule 3 | Author: Larry Hastings 4 | Status: Final 5 | Type: Informational 6 | Topic: Release 7 | Created: 22-Sep-2014 8 | Python-Version: 3.5 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for 15 | Python 3.5. 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 September 2015. 21 | 22 | 23 | Release Manager and Crew 24 | ======================== 25 | 26 | - 3.5 Release Manager: Larry Hastings 27 | - Windows installers: Steve Dower 28 | - Mac installers: Ned Deily 29 | - Documentation: Georg Brandl 30 | 31 | 32 | Release Schedule 33 | ================ 34 | 35 | Python 3.5 has now reached its end-of-life and has been retired. 36 | No more releases will be made. 37 | 38 | These are all the historical releases of Python 3.5, 39 | including their release dates. 40 | 41 | - 3.5.0 alpha 1: February 8, 2015 42 | - 3.5.0 alpha 2: March 9, 2015 43 | - 3.5.0 alpha 3: March 29, 2015 44 | - 3.5.0 alpha 4: April 19, 2015 45 | - 3.5.0 beta 1: May 24, 2015 46 | (Beta 1 is also "feature freeze"--no new features beyond this point.) 47 | - 3.5.0 beta 2: May 31, 2015 48 | - 3.5.0 beta 3: July 5, 2015 49 | - 3.5.0 beta 4: July 26, 2015 50 | - 3.5.0 release candidate 1: August 10, 2015 51 | - 3.5.0 release candidate 2: August 25, 2015 52 | - 3.5.0 release candidate 3: September 7, 2015 53 | - 3.5.0 final: September 13, 2015 54 | - 3.5.1 release candidate 1: November 22, 2015 55 | - 3.5.1 final: December 6, 2015 56 | - 3.5.2 release candidate 1: Sunday, June 12, 2016 57 | - 3.5.2 final: Sunday, June 26, 2016 58 | - 3.5.3 candidate 1: January 2, 2017 59 | - 3.5.3 final: January 17, 2017 60 | - 3.5.4 candidate 1: July 25, 2017 61 | - 3.5.4 final: August 8, 2017 62 | - 3.5.5 candidate 1: January 23, 2018 63 | - 3.5.5 final: February 4, 2018 64 | - 3.5.6 candidate 1: July 19, 2018 65 | - 3.5.6 final: August 2, 2018 66 | - 3.5.7 candidate 1: March 4, 2019 67 | - 3.5.7 final: March 18, 2019 68 | - 3.5.8 candidate 1: September 9, 2019 69 | - 3.5.8 candidate 2: October 12, 2019 70 | - 3.5.8 final: October 29, 2019 71 | - 3.5.9 final: November 1, 2019 72 | - 3.5.10 rc1: August 21, 2020 73 | - 3.5.10 final: September 5, 2020 74 | 75 | 76 | 77 | 78 | Features for 3.5 79 | ================ 80 | 81 | * :pep:`441`, improved Python zip application support 82 | * :pep:`448`, additional unpacking generalizations 83 | * :pep:`461`, "%-formatting" for bytes and bytearray objects 84 | * :pep:`465`, a new operator ("@") for matrix multiplication 85 | * :pep:`471`, os.scandir(), a fast new directory traversal function 86 | * :pep:`475`, adding support for automatic retries of interrupted system calls 87 | * :pep:`479`, change StopIteration handling inside generators 88 | * :pep:`484`, the typing module, a new standard for type annotations 89 | * :pep:`485`, math.isclose(), a function for testing approximate equality 90 | * :pep:`486`, making the Windows Python launcher aware of virtual environments 91 | * :pep:`488`, eliminating .pyo files 92 | * :pep:`489`, a new and improved mechanism for loading extension modules 93 | * :pep:`492`, coroutines with async and await syntax 94 | 95 | 96 | Copyright 97 | ========= 98 | 99 | This document has been placed in the public domain. 100 | -------------------------------------------------------------------------------- /peps/pep-0480-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0480-1.png -------------------------------------------------------------------------------- /peps/pep-0495-daylightsavings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/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/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0525-1.png -------------------------------------------------------------------------------- /peps/pep-0550-hamt_vs_dict-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0550-hamt_vs_dict-v2.png -------------------------------------------------------------------------------- /peps/pep-0550-hamt_vs_dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0550-hamt_vs_dict.png -------------------------------------------------------------------------------- /peps/pep-0550-lookup_hamt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/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 | Created: 08-Sep-2017 7 | Python-Version: 3.7 8 | Post-History: 09-Sep-2017 9 | Resolution: https://mail.python.org/pipermail/python-dev/2017-September/149438.html 10 | 11 | 12 | Abstract 13 | ======== 14 | 15 | This PEP proposes adding a new built-in function called ``noop()`` which does 16 | nothing but return ``None``. 17 | 18 | 19 | Rationale 20 | ========= 21 | 22 | It is trivial to implement a no-op function in Python. It's so easy in fact 23 | that many people do it many times over and over again. It would be useful in 24 | many cases to have a common built-in function that does nothing. 25 | 26 | One use case would be for :pep:`553`, where you could set the breakpoint 27 | environment variable to the following in order to effectively disable it:: 28 | 29 | $ setenv PYTHONBREAKPOINT=noop 30 | 31 | 32 | Implementation 33 | ============== 34 | 35 | The Python equivalent of the ``noop()`` function is exactly:: 36 | 37 | def noop(*args, **kws): 38 | return None 39 | 40 | The C built-in implementation is available as a pull request [1]_. 41 | 42 | 43 | Rejected alternatives 44 | ===================== 45 | 46 | ``noop()`` returns something 47 | ---------------------------- 48 | 49 | YAGNI. 50 | 51 | This is rejected because it complicates the semantics. For example, if you 52 | always return both ``*args`` and ``**kws``, what do you return when none of 53 | those are given? Returning a tuple of ``((), {})`` is kind of ugly, but 54 | provides consistency. But you might also want to just return ``None`` since 55 | that's also conceptually what the function was passed. 56 | 57 | Or, what if you pass in exactly one positional argument, e.g. ``noop(7)``. Do 58 | you return ``7`` or ``((7,), {})``? And so on. 59 | 60 | The author claims that you won't ever need the return value of ``noop()`` so 61 | it will always return ``None``. 62 | 63 | Coghlan's Dialogs (edited for formatting): 64 | 65 | My counterargument to this would be ``map(noop, iterable)``, 66 | ``sorted(iterable, key=noop)``, etc. (``filter``, ``max``, and 67 | ``min`` all accept callables that accept a single argument, as do 68 | many of the itertools operations). 69 | 70 | Making ``noop()`` a useful default function in those cases just 71 | needs the definition to be:: 72 | 73 | def noop(*args, **kwds): 74 | return args[0] if args else None 75 | 76 | The counterargument to the counterargument is that using ``None`` 77 | as the default in all these cases is going to be faster, since it 78 | lets the algorithm skip the callback entirely, rather than calling 79 | it and having it do nothing useful. 80 | 81 | 82 | References 83 | ========== 84 | 85 | .. [1] https://github.com/python/cpython/pull/3480 86 | 87 | 88 | Copyright 89 | ========= 90 | 91 | This document has been placed in the public domain. 92 | -------------------------------------------------------------------------------- /peps/pep-0602-example-release-calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0602-example-release-calendar.png -------------------------------------------------------------------------------- /peps/pep-0602-example-release-calendar.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0602-example-release-calendar.pptx -------------------------------------------------------------------------------- /peps/pep-0602-overlapping-support-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0602-overlapping-support-matrix.png -------------------------------------------------------------------------------- /peps/pep-0602-overlapping-support-matrix.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0602-overlapping-support-matrix.pptx -------------------------------------------------------------------------------- /peps/pep-0603-hamt_vs_dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0603-hamt_vs_dict.png -------------------------------------------------------------------------------- /peps/pep-0603-lookup_hamt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0603-lookup_hamt.png -------------------------------------------------------------------------------- /peps/pep-0605-example-release-calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0605-example-release-calendar.png -------------------------------------------------------------------------------- /peps/pep-0605-overlapping-support-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0605-overlapping-support-matrix.png -------------------------------------------------------------------------------- /peps/pep-0605/example-release-calendar.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0605/example-release-calendar.odp -------------------------------------------------------------------------------- /peps/pep-0605/overlapping-support-matrix.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0605/overlapping-support-matrix.odp -------------------------------------------------------------------------------- /peps/pep-0628.rst: -------------------------------------------------------------------------------- 1 | PEP: 628 2 | Title: Add ``math.tau`` 3 | Author: Alyssa Coghlan 4 | Status: Final 5 | Type: Standards Track 6 | Created: 28-Jun-2011 7 | Python-Version: 3.6 8 | Post-History: 28-Jun-2011 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | In honour of Tau Day 2011, this PEP proposes the addition of the circle 15 | constant ``math.tau`` to the Python standard library. 16 | 17 | The concept of ``tau`` (``τ``) is based on the observation that the ratio of a 18 | circle's circumference to its radius is far more fundamental and interesting 19 | than the ratio between its circumference and diameter. It is simply a matter 20 | of assigning a name to the value ``2 * pi`` (``2π``). 21 | 22 | 23 | PEP Acceptance 24 | ============== 25 | 26 | This PEP is now `accepted`_ and ``math.tau`` will be a part of Python 3.6. 27 | Happy birthday Alyssa! 28 | 29 | The idea in this PEP has been implemented in the auspiciously named 30 | `issue 12345`_. 31 | 32 | .. _accepted: https://bugs.python.org/issue12345#msg272287 33 | .. _issue 12345: http://bugs.python.org/issue12345 34 | 35 | 36 | The Rationale for Tau 37 | ===================== 38 | 39 | ``pi`` is defined as the ratio of a circle's circumference to its diameter. 40 | However, a circle is defined by its centre point and its *radius*. This is 41 | shown clearly when we note that the parameter of integration to go from a 42 | circle's circumference to its area is the radius, not the diameter. If we 43 | use the diameter instead we have to divide by four to get rid of the 44 | extraneous multiplier. 45 | 46 | When working with radians, it is trivial to convert any given fraction of a 47 | circle to a value in radians in terms of ``tau``. A quarter circle is 48 | ``tau/4``, a half circle is ``tau/2``, seven 25ths is ``7*tau/25``, etc. In 49 | contrast with the equivalent expressions in terms of ``pi`` (``pi/2``, ``pi``, 50 | ``14*pi/25``), the unnecessary and needlessly confusing multiplication by 51 | two is gone. 52 | 53 | 54 | Other Resources 55 | =============== 56 | 57 | I've barely skimmed the surface of the many examples put forward to point out 58 | just how much *easier* and more *sensible* many aspects of mathematics become 59 | when conceived in terms of ``tau`` rather than ``pi``. If you don't find my 60 | specific examples sufficiently persuasive, here are some more resources that 61 | may be of interest: 62 | 63 | * Michael Hartl is the primary instigator of Tau Day in his `Tau Manifesto`_ 64 | * Bob Palais, the author of the original mathematics journal article 65 | highlighting the problems with ``pi`` has `a page of resources`_ on the 66 | topic 67 | * For those that prefer videos to written text, `Pi is wrong!`_ and 68 | `Pi is (still) wrong`_ are available on YouTube 69 | 70 | .. _Tau Manifesto: http://tauday.com/ 71 | .. _Pi is (still) wrong: http://www.youtube.com/watch?v=jG7vhMMXagQ 72 | .. _Pi is wrong!: http://www.youtube.com/watch?v=IF1zcRoOVN0 73 | .. _a page of resources: http://www.math.utah.edu/~palais/pi.html 74 | 75 | 76 | Copyright 77 | ========= 78 | 79 | This document has been placed in the public domain. 80 | -------------------------------------------------------------------------------- /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-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 | - 3.12.4: Thursday, 2024-06-06 64 | - 3.12.5: Tuesday, 2024-08-06 65 | - 3.12.6: Friday, 2024-09-06 66 | - 3.12.7: Tuesday, 2024-10-01 67 | - 3.12.8: Tuesday, 2024-12-03 68 | - 3.12.9: Tuesday, 2025-02-04 69 | - 3.12.10: Tuesday, 2025-04-08 (final regular bugfix release with binary installers) 70 | 71 | Source-only security fix releases 72 | --------------------------------- 73 | 74 | Provided irregularly on an as-needed basis until October 2028. 75 | 76 | 3.12 Lifespan 77 | ------------- 78 | 79 | 3.12 received bugfix updates approximately every 2 months for 80 | approximately 18 months. Some time after the release of 3.13.0 final, 81 | the tenth and final 3.12 bugfix update was released. After that, 82 | it is expected that security updates (source only) will be released 83 | until 5 years after the release of 3.12.0 final, so until approximately 84 | October 2028. 85 | 86 | 87 | Features for 3.12 88 | ================= 89 | 90 | New features can be found in `What’s New In Python 3.12 91 | `__. 92 | 93 | 94 | Copyright 95 | ========= 96 | 97 | This document is placed in the public domain or under the CC0-1.0-Universal 98 | license, whichever is more permissive. 99 | -------------------------------------------------------------------------------- /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 | - 3.13.0 beta 2: Wednesday, 2024-06-05 48 | - 3.13.0 beta 3: Thursday, 2024-06-27 49 | - 3.13.0 beta 4: Thursday, 2024-07-18 50 | - 3.13.0 candidate 1: Thursday, 2024-08-01 51 | - 3.13.0 candidate 2: Friday, 2024-09-06 52 | - 3.13.0 candidate 3: Tuesday, 2024-10-01 53 | - 3.13.0 final: Monday, 2024-10-07 54 | 55 | Bugfix releases 56 | --------------- 57 | 58 | Actual: 59 | 60 | - 3.13.1: Tuesday, 2024-12-03 61 | - 3.13.2: Tuesday, 2025-02-04 62 | - 3.13.3: Tuesday, 2025-04-08 63 | 64 | Expected: 65 | 66 | - 3.13.4: Tuesday, 2025-06-03 67 | - 3.13.5: Tuesday, 2025-08-05 68 | - 3.13.6: Tuesday, 2025-10-07 69 | - 3.13.7: Tuesday, 2025-12-02 70 | - 3.13.8: Tuesday, 2026-02-03 71 | - 3.13.9: Tuesday, 2026-04-07 72 | - 3.13.10: Tuesday, 2026-06-09 73 | - 3.13.11: Tuesday, 2026-08-04 74 | - 3.13.12: Tuesday, 2026-10-06 75 | 76 | 77 | Source-only security fix releases 78 | --------------------------------- 79 | 80 | Provided irregularly on an as-needed basis until October 2029. 81 | 82 | 83 | 3.13 Lifespan 84 | ------------- 85 | 86 | 3.13 will receive bugfix updates approximately every 2 months for 87 | approximately 24 months. Around the time of the release of 3.15.0 final, the 88 | final 3.13 bugfix update will be released. After that, it is expected that 89 | security updates (source only) will be released until 5 years after the 90 | release of 3.13.0 final, so until approximately October 2029. 91 | 92 | 93 | Copyright 94 | ========= 95 | 96 | This document is placed in the public domain or under the CC0-1.0-Universal 97 | license, whichever is more permissive. 98 | -------------------------------------------------------------------------------- /peps/pep-0739/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0", 3 | "base_prefix": "/usr", 4 | "base_interpreter": "/usr/bin/python", 5 | "platform": "linux-x86_64", 6 | "language": { 7 | "version": "3.14", 8 | "version_info": { 9 | "major": 3, 10 | "minor": 14, 11 | "micro": 0, 12 | "releaselevel": "alpha", 13 | "serial": 0 14 | } 15 | }, 16 | "implementation": { 17 | "name": "cpython", 18 | "version": { 19 | "major": 3, 20 | "minor": 14, 21 | "micro": 0, 22 | "releaselevel": "alpha", 23 | "serial": 0 24 | }, 25 | "hexversion": 51249312, 26 | "cache_tag": "cpython-314", 27 | "_multiarch": "x86_64-linux-gnu" 28 | }, 29 | "abi": { 30 | "flags": ["t", "d"], 31 | "extension_suffix": ".cpython-314-x86_64-linux-gnu.so", 32 | "stable_abi_suffix": ".abi3.so" 33 | }, 34 | "suffixes": { 35 | "source": [".py"], 36 | "bytecode": [".pyc"], 37 | "optimized_bytecode": [".pyc"], 38 | "debug_bytecode": [".pyc"], 39 | "extensions": [".cpython-314-x86_64-linux-gnu.so", ".abi3.so", ".so"] 40 | }, 41 | "libpython": { 42 | "dynamic": "/usr/lib/libpython3.14.so.1.0", 43 | "dynamic_stableabi": "/usr/lib/libpython3.so", 44 | "static": "/usr/lib/python3.14/config-3.14-x86_64-linux-gnu/libpython3.14.a", 45 | "link_extensions": true 46 | }, 47 | "c_api": { 48 | "headers": "/usr/include/python3.14", 49 | "pkgconfig_path": "/usr/lib/pkgconfig" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /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 | Actual: 37 | 38 | - 3.14 development begins: Wednesday, 2024-05-08 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: Wednesday, 2025-05-07 47 | (No new features beyond this point.) 48 | - 3.14.0 beta 2: Monday, 2025-05-26 49 | 50 | Expected: 51 | 52 | - 3.14.0 beta 3: Tuesday, 2025-06-17 53 | - 3.14.0 beta 4: Tuesday, 2025-07-08 54 | - 3.14.0 candidate 1: Tuesday, 2025-07-22 55 | - 3.14.0 candidate 2: Tuesday, 2025-08-26 56 | - 3.14.0 final: Tuesday, 2025-10-07 57 | 58 | Subsequent bugfix releases every two months. 59 | 60 | 61 | 3.14 lifespan 62 | ------------- 63 | 64 | Python 3.14 will receive bugfix updates approximately every two months for 65 | approximately 24 months. Around the time of the release of 3.16.0 final, the 66 | final 3.14 bugfix update will be released. After that, it is expected that 67 | security updates (source only) will be released until five years after the 68 | release of 3.14.0 final, so until approximately October 2030. 69 | 70 | 71 | Copyright 72 | ========= 73 | 74 | This document is placed in the public domain or under the 75 | CC0-1.0-Universal license, whichever is more permissive. 76 | -------------------------------------------------------------------------------- /peps/pep-0777/appendix-dl-by-installer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0777/appendix-dl-by-installer.png -------------------------------------------------------------------------------- /peps/pep-0777/appendix-dl-by-pip-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-0777/appendix-dl-by-pip-version.png -------------------------------------------------------------------------------- /peps/pep-0790.rst: -------------------------------------------------------------------------------- 1 | PEP: 790 2 | Title: Python 3.15 Release Schedule 3 | Author: Hugo van Kemenade 4 | Status: Active 5 | Type: Informational 6 | Topic: Release 7 | Created: 26-Apr-2025 8 | Python-Version: 3.15 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This document describes the development and release schedule for Python 3.15. 15 | 16 | Release manager and crew 17 | ======================== 18 | 19 | - 3.15 release manager: Hugo van Kemenade 20 | - Windows installers: Steve Dower 21 | - Mac installers: Ned Deily 22 | - Documentation: Julien Palard 23 | 24 | 25 | Release schedule 26 | ================ 27 | 28 | 3.15.0 schedule 29 | --------------- 30 | 31 | The dates below use a 17-month development period that results in a 12-month 32 | release cadence between feature versions, as defined by :pep:`602`. 33 | 34 | Expected: 35 | 36 | - 3.15 development begins: Tuesday, 2025-05-06 37 | - 3.15.0 alpha 1: Tuesday, 2025-10-14 38 | - 3.15.0 alpha 2: Tuesday, 2025-11-18 39 | - 3.15.0 alpha 3: Tuesday, 2025-12-16 40 | - 3.15.0 alpha 4: Tuesday, 2026-01-13 41 | - 3.15.0 alpha 5: Tuesday, 2026-02-10 42 | - 3.15.0 alpha 6: Tuesday, 2026-03-10 43 | - 3.15.0 alpha 7: Tuesday, 2026-04-07 44 | - 3.15.0 beta 1: Tuesday, 2026-05-05 45 | (No new features beyond this point.) 46 | - 3.15.0 beta 2: Tuesday, 2026-05-26 47 | - 3.15.0 beta 3: Tuesday, 2026-06-16 48 | - 3.15.0 beta 4: Tuesday, 2026-07-14 49 | - 3.15.0 candidate 1: Tuesday, 2026-07-28 50 | - 3.15.0 candidate 2: Tuesday, 2026-09-01 51 | - 3.15.0 final: Thursday, 2026-10-01 52 | 53 | Subsequent bugfix releases every two months. 54 | 55 | 56 | 3.15 lifespan 57 | ------------- 58 | 59 | * Python 3.15 will receive bugfix updates approximately every second month for 60 | two years. 61 | * Around the time of the release of 3.18.0 final, the final 3.15 bugfix update 62 | will be released. 63 | * After that, it is expected that security updates (source only) will be 64 | released for the next three years, until five years after the release of 65 | 3.15.0 final, so until approximately October 2031. 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-0793/examplemodule.c: -------------------------------------------------------------------------------- 1 | /* 2 | Example module with C-level module-global state, and a simple function to 3 | update and query it. 4 | Once compiled and renamed to not include a version tag (for example 5 | examplemodule.so on Linux), this will run succesfully on both regular 6 | and free-threaded builds. 7 | 8 | Python usage: 9 | 10 | import examplemodule 11 | print(examplemodule.increment_value()) # 0 12 | print(examplemodule.increment_value()) # 1 13 | print(examplemodule.increment_value()) # 2 14 | print(examplemodule.increment_value()) # 3 15 | 16 | */ 17 | 18 | // Avoid CPython-version-specific ABI (inline functions & macros): 19 | #define Py_LIMITED_API 0x030f0000 // 3.15 20 | 21 | #include 22 | 23 | typedef struct { 24 | int value; 25 | } examplemodule_state; 26 | 27 | static PyObject * 28 | increment_value(PyObject *module, PyObject *_ignored) 29 | { 30 | examplemodule_state *state = PyModule_GetState(module); 31 | int result = ++(state->value); 32 | return PyLong_FromLong(result); 33 | } 34 | 35 | static PyMethodDef examplemodule_methods[] = { 36 | {"increment_value", increment_value, METH_NOARGS}, 37 | {NULL} 38 | }; 39 | 40 | static int 41 | examplemodule_exec(PyObject *module) { 42 | examplemodule_state *state = PyModule_GetState(module); 43 | state->value = -1; 44 | return 0; 45 | } 46 | 47 | PyDoc_STRVAR(examplemodule_doc, "Example extension."); 48 | 49 | static PyModuleDef_Slot examplemodule_slots[] = { 50 | {Py_mod_name, "examplemodule"}, 51 | {Py_mod_doc, (char*)examplemodule_doc}, 52 | {Py_mod_exec, (void*)examplemodule_exec}, 53 | {Py_mod_methods, examplemodule_methods}, 54 | {Py_mod_state_size, (void*)sizeof(examplemodule_state)}, 55 | {0} 56 | }; 57 | 58 | // Avoid "implicit declaration of function" warning: 59 | PyMODEXPORT_FUNC PyModExport_examplemodule(PyObject *); 60 | 61 | PyMODEXPORT_FUNC 62 | PyModExport_examplemodule(PyObject *spec) 63 | { 64 | return examplemodule_slots; 65 | } 66 | -------------------------------------------------------------------------------- /peps/pep-0801.rst: -------------------------------------------------------------------------------- 1 | PEP: 801 2 | Title: Reserved 3 | Author: Barry Warsaw 4 | Status: Active 5 | Type: Informational 6 | Created: 21-Jun-2018 7 | 8 | 9 | Abstract 10 | ======== 11 | 12 | This PEP is reserved for future use, because 13 | `We are the 801 `_. 14 | Contact the author for details. 15 | 16 | 17 | Copyright 18 | ========= 19 | 20 | This document has been placed in the public domain. 21 | -------------------------------------------------------------------------------- /peps/pep-3120.rst: -------------------------------------------------------------------------------- 1 | PEP: 3120 2 | Title: Using UTF-8 as the default source encoding 3 | Author: Martin von Löwis 4 | Status: Final 5 | Type: Standards Track 6 | Created: 15-Apr-2007 7 | Python-Version: 3.0 8 | Post-History: 9 | 10 | 11 | Specification 12 | ============= 13 | 14 | This PEP proposes to change the default source encoding from ASCII to 15 | UTF-8. Support for alternative source encodings (:pep:`263`) continues to 16 | exist; an explicit encoding declaration takes precedence over the 17 | default. 18 | 19 | 20 | A Bit of History 21 | ================ 22 | 23 | In Python 1, the source encoding was unspecified, except that the 24 | source encoding had to be a superset of the system's basic execution 25 | character set (i.e. an ASCII superset, on most systems). The source 26 | encoding was only relevant for the lexis itself (bytes representing 27 | letters for keywords, identifiers, punctuation, line breaks, etc). 28 | The contents of a string literal was copied literally from the file 29 | on source. 30 | 31 | In Python 2.0, the source encoding changed to Latin-1 as a side effect 32 | of introducing Unicode. For Unicode string literals, the characters 33 | were still copied literally from the source file, but widened on a 34 | character-by-character basis. As Unicode gives a fixed interpretation 35 | to code points, this algorithm effectively fixed a source encoding, at 36 | least for files containing non-ASCII characters in Unicode literals. 37 | 38 | :pep:`263` identified the problem that you can use only those Unicode 39 | characters in a Unicode literal which are also in Latin-1, and 40 | introduced a syntax for declaring the source encoding. If no source 41 | encoding was given, the default should be ASCII. For compatibility 42 | with Python 2.0 and 2.1, files were interpreted as Latin-1 for a 43 | transitional period. This transition ended with Python 2.5, which 44 | gives an error if non-ASCII characters are encountered and no source 45 | encoding is declared. 46 | 47 | Rationale 48 | ========= 49 | 50 | With :pep:`263`, using arbitrary non-ASCII characters in a Python file is 51 | possible, but tedious. One has to explicitly add an encoding 52 | declaration. Even though some editors (like IDLE and Emacs) support 53 | the declarations of :pep:`263`, many editors still do not (and never 54 | will); users have to explicitly adjust the encoding which the editor 55 | assumes on a file-by-file basis. 56 | 57 | When the default encoding is changed to UTF-8, adding non-ASCII text 58 | to Python files becomes easier and more portable: On some systems, 59 | editors will automatically choose UTF-8 when saving text (e.g. on Unix 60 | systems where the locale uses UTF-8). On other systems, editors will 61 | guess the encoding when reading the file, and UTF-8 is easy to 62 | guess. Yet other editors support associating a default encoding with a 63 | file extension, allowing users to associate .py with UTF-8. 64 | 65 | For Python 2, an important reason for using non-UTF-8 encodings was 66 | that byte string literals would be in the source encoding at run-time, 67 | allowing then to output them to a file or render them to the user 68 | as-is. With Python 3, all strings will be Unicode strings, so the 69 | original encoding of the source will have no impact at run-time. 70 | 71 | Implementation 72 | ============== 73 | 74 | The parser needs to be changed to accept bytes > 127 if no source 75 | encoding is specified; instead of giving an error, it needs to check 76 | that the bytes are well-formed UTF-8 (decoding is not necessary, 77 | as the parser converts all source code to UTF-8, anyway). 78 | 79 | IDLE needs to be changed to use UTF-8 as the default encoding. 80 | 81 | 82 | Copyright 83 | ========= 84 | 85 | This document has been placed in the public domain. 86 | -------------------------------------------------------------------------------- /peps/pep-3129.rst: -------------------------------------------------------------------------------- 1 | PEP: 3129 2 | Title: Class Decorators 3 | Author: Collin Winter 4 | Status: Final 5 | Type: Standards Track 6 | Created: 01-May-2007 7 | Python-Version: 3.0 8 | Post-History: 07-May-2007 9 | 10 | 11 | Abstract 12 | ======== 13 | 14 | This PEP proposes class decorators, an extension to the function 15 | and method decorators introduced in :pep:`318`. 16 | 17 | 18 | Rationale 19 | ========= 20 | 21 | When function decorators were originally debated for inclusion in 22 | Python 2.4, class decorators were seen as 23 | :pep:`obscure and unnecessary <318#motivation>` 24 | thanks to metaclasses. After several years' experience 25 | with the Python 2.4.x series of releases and an increasing 26 | familiarity with function decorators and their uses, the BDFL and 27 | the community re-evaluated class decorators and recommended their 28 | inclusion in Python 3.0 [#approval]_. 29 | 30 | The motivating use-case was to make certain constructs more easily 31 | expressed and less reliant on implementation details of the CPython 32 | interpreter. While it is possible to express class decorator-like 33 | functionality using metaclasses, the results are generally 34 | unpleasant and the implementation highly fragile [#motivation]_. In 35 | addition, metaclasses are inherited, whereas class decorators are not, 36 | making metaclasses unsuitable for some, single class-specific uses of 37 | class decorators. The fact that large-scale Python projects like Zope 38 | were going through these wild contortions to achieve something like 39 | class decorators won over the BDFL. 40 | 41 | 42 | Semantics 43 | ========= 44 | 45 | The semantics and design goals of class decorators are the same as 46 | for function decorators (:pep:`318#current-syntax`, :pep:`318#design-goals`); 47 | the only 48 | difference is that you're decorating a class instead of a function. 49 | The following two snippets are semantically identical:: 50 | 51 | class A: 52 | pass 53 | A = foo(bar(A)) 54 | 55 | 56 | @foo 57 | @bar 58 | class A: 59 | pass 60 | 61 | For a detailed examination of decorators, please refer to :pep:`318`. 62 | 63 | 64 | Implementation 65 | ============== 66 | 67 | Adapting Python's grammar to support class decorators requires 68 | modifying two rules and adding a new rule:: 69 | 70 | funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite 71 | 72 | compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | 73 | with_stmt | funcdef | classdef 74 | 75 | need to be changed to :: 76 | 77 | decorated: decorators (classdef | funcdef) 78 | 79 | funcdef: 'def' NAME parameters ['->' test] ':' suite 80 | 81 | compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | 82 | with_stmt | funcdef | classdef | decorated 83 | 84 | Adding ``decorated`` is necessary to avoid an ambiguity in the 85 | grammar. 86 | 87 | The Python AST and bytecode must be modified accordingly. 88 | 89 | A reference implementation [#implementation]_ has been provided by 90 | Jack Diederich. 91 | 92 | 93 | Acceptance 94 | ========== 95 | 96 | There was virtually no discussion following the posting of this PEP, 97 | meaning that everyone agreed it should be accepted. 98 | 99 | The patch was committed to Subversion as revision 55430. 100 | 101 | 102 | References 103 | ========== 104 | 105 | .. [#approval] 106 | https://mail.python.org/pipermail/python-dev/2006-March/062942.html 107 | 108 | .. [#motivation] 109 | https://mail.python.org/pipermail/python-dev/2006-March/062888.html 110 | 111 | .. [#implementation] 112 | https://bugs.python.org/issue1671208 113 | 114 | 115 | 116 | Copyright 117 | ========= 118 | 119 | This document has been placed in the public domain. 120 | -------------------------------------------------------------------------------- /peps/pep-3147-1.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-3147-1.dia -------------------------------------------------------------------------------- /peps/pep-3147-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-3147-1.png -------------------------------------------------------------------------------- /peps/pep-789-example-no-yield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-789-example-no-yield.png -------------------------------------------------------------------------------- /peps/pep-789-example-yield-allowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-789-example-yield-allowed.png -------------------------------------------------------------------------------- /peps/pep-789-example-yield-errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python/peps/3158ed354dd41b6af5ef48ebbbeed77c74d591af/peps/pep-789-example-yield-errors.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, < 8.1.0 6 | docutils >= 0.19.0 7 | sphinx-notfound-page >= 1.0.2 8 | 9 | # For tests 10 | pytest 11 | pytest-cov 12 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------