You're right, the example could be better. It works like so:
beaglevote's METADATA: Provides-Extra: quux Provides-Extra: pdf Requires-Dist: doghouse Requires-Dist: sphinx; extra == 'quux' Requires-Dist: reportlab; extra == 'pdf' "install beaglevote" -> evaluate Requires-Dist: with extra == None: -> requires doghouse "install beaglevote[pdf]" -> set(Requires-Dist: with extra == None) + set(Requires-Dist: with extra == 'pdf') -> requires doghouse, reportlab "install beaglevote[quux]" -> set(Requires-Dist: with extra == None) + set(Requires-Dist: with extra == 'quux') -> requires doghouse, sphinx "install beaglevote[pearl]" -> error, 'pearl' is not mentioned in Provides-Extra: Extras are only supposed to add requirements. To make things as predictable as possible, extra is a string, not a list, requirements are always evaluated with extra == None first, and the requirements are re-evaluated for each requested extra individually. This is to avoid mischief like Requires-Dist: something; 'foo' in extra and not 'bar' in extra Requires-Dist: another; extra != 'quux' Parenthesis would be desirable so you can say: Requires-Dist: splort; (python_version < '2.6' or sys.platform == 'win32') and extra == 'blurble' _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig