Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 423 – Naming conventions and recipes related to packaging

Author:
Benoit Bryon <benoit at marmelune.net>
Discussions-To:
Distutils-SIG list
Status:
Deferred
Type:
Informational
Topic:
Packaging
Created:
24-May-2012
Post-History:


Table of Contents

Abstract

This document deals with:

  • names of Python projects,
  • names of Python packages or modules being distributed,
  • namespace packages.

It provides guidelines and recipes for distribution authors:

PEP Deferral

Further consideration of this PEP has been deferred at least until afterPEP 426 (package metadata 2.0) and related updates have been resolved.

Terminology

Reference ispackaging terminology in Python documentation.

Relationship with other PEPs

  • PEP 8deals with code style guide, including names of Pythonpackages and modules. It covers syntax of package/modules names.
  • PEP 345 deals with packaging metadata, and defines name argumentof thepackaging.core.setup() function.
  • PEP 420 deals with namespace packages. It brings support ofnamespace packages to Python core. Before, namespaces packages wereimplemented by external libraries.
  • PEP 3108 deals with transition between Python 2.x and Python 3.xapplied to standard library: some modules to be deleted, some to berenamed. It points out that naming conventions matter and is anexample of transition plan.

Overview

Here is a summarized list of guidelines you should follow to choosenames:

If in doubt, ask

If you feel unsure after reading this document, askPythoncommunity on IRC or on a mailing list.

Top-level namespace relates to code ownership

This helps avoid clashes between project names.

Ownership could be:

  • an individual.Example:gp.fileupload is owned and maintained by GaelPasgrimaud.
  • an organization.Examples:
    • zest.releaser is owned and maintained by Zest Software.
    • Django is owned and maintained by the Django SoftwareFoundation.
  • a group or community.Example:sphinx is maintained by developers of the Sphinxproject, not only by its author, Georg Brandl.
  • a group or community related to another package.Example:collective.recaptcha is owned by its author: DavidGlick, Groundwire. But the “collective” namespace is owned by Plonecommunity.

Respect ownership

Understand the purpose of namespace before you use it.

Don’t plug into a namespace you don’t own, unless explicitlyauthorized.

If in doubt, ask.

As an example, don’t plug in “django.contrib” namespace because it ismanaged by Django’s core contributors.

Exceptions can be defined by project authors. SeeOrganize communitycontributions below.

Also, this rule applies to non-Python projects.

As an example, don’t use “apache” as top-level namespace: “Apache” isthe name of an existing project (in the case of “Apache”, it is also atrademark).

Private (including closed-source) projects use a namespace

… because private projects are owned by somebody. So apply theownership rule.

For internal/customer projects, use your company name as thenamespace.

This rule applies to closed-source projects.

As an example, if you are creating a “climbing” project for the“Python Sport” company: use “pythonsport.climbing” name, even if it isclosed source.

Individual projects use a namespace

… because they are owned by individuals. So apply theownership rule.

There is no shame in releasing a project as open source even if it hasan “internal” or “individual” name.

If the project comes to a point where the author wants to changeownership (i.e. the project no longer belongs to an individual), keepin mindit is easy to rename the project.

Community-owned projects can avoid namespace packages

If your project is generic enough (i.e. it is not a contrib to anotherproduct or framework), you can avoid namespace packages. The basecondition is generally that your project is owned by a group (i.e. thedevelopment team) which is dedicated to this project.

Only use a “shared” namespace if you really intend the code to becommunity owned.

As an example,sphinx project belongs to the Sphinx developmentteam. There is no need to have some “sphinx” namespace package withonly one “sphinx.sphinx” project inside.

In doubt, use an individual/organization namespace

If your project is really experimental, best choice is to use anindividual or organization namespace:

  • it allows projects to be released early.
  • it won’t block a name if the project is abandoned.
  • it doesn’t block future changes. When a project becomes mature andthere is no reason to keep individual ownership,it remainspossible to rename the project.

Use a single name

Distribute only one package (or only one module) per project, and usepackage (or module) name as project name.

  • It avoids possible confusion between project name and distributedpackage or module name.
  • It makes the name consistent.
  • It is explicit: when one sees project name, he guessespackage/module name, and vice versa.
  • It also limits implicit clashes between package/module names.By using a single name, when you register a project name toPyPI,you also perform a basic package/module name availabilityverification.

    As an example,pipeline,python-pipeline anddjango-pipeline all distribute a package or module called“pipeline”. So installing two of them leads to errors. This issuewouldn’t have occurred if these distributions used a single name.

Yes:

  • Package name: “kheops.pyramid”,i.e.importkheops.pyramid
  • Project name: “kheops.pyramid”,i.e.pipinstallkheops.pyramid

No:

  • Package name: “kheops”
  • Project name: “KheopsPyramid”

Note

For historical reasons,PyPI contains many distributions whereproject and distributed package/module names differ.

Multiple packages/modules should be rare

Technically, Python distributions can provide multiple packages and/ormodules. Seesetup script reference for details.

Some distributions actually do.As an example,setuptools anddistribute are both declaring“pkg_resources”, “easy_install” and “site” modules in addition torespective “setuptools” and “distribute” packages.

Consider this use case as exceptional. In most cases, you don’t needthis feature. So a distribution should provide only one package ormodule at a time.

Distinct names should be rare

A notable exception to theUse a single name rule is when youexplicitly need distinct names.

As an example, thePillow project provides an alternative to theoriginalPIL distribution. Both projects distribute a “PIL”package.

Consider this use case as exceptional. In most cases, you don’t needthis feature. So a distributed package name should be equal to projectname.

Follow PEP 8 for syntax of package and module names

PEP 8 applies to names of Python packages and modules.

If youUse a single name,PEP 8also applies to project names.The exceptions are namespace packages, where dots are required inproject name.

Pick memorable names

One important thing about a project name is that it be memorable.

As an example,celery is not a meaningful name. At first, it is notobvious that it deals with message queuing. But it is memorable,partly because it can be used to feed aRabbitMQ server.

Pick meaningful names

Ask yourself “how would I describe in one sentence what this name isfor?”, and then “could anyone have guessed that by looking at thename?”.

As an example,DateUtils is a meaningful name. It is obvious thatit deals with utilities for dates.

When you are using namespaces, try to make each part meaningful.

Use packaging metadata

Consider project names as unique identifiers on PyPI:

  • it is important that these identifiers remain human-readable.
  • it is even better when these identifiers are meaningful.
  • but the primary purpose of identifiers is not to classify ordescribe projects.

Classifiers and keywords metadata are made for categorization ofdistributions. Summary and description metadata are meant todescribe the project.

As an example, there is a “Framework :: Twisted” classifier. Evenif names are quite heterogeneous (they don’t follow a particularpattern), we get the list.

In order toOrganize community contributions, conventions aboutnames and namespaces matter, but conventions about metadata should beeven more important.

As an example, we can find Plone portlets in many places:

  • plone.portlet.*
  • collective.portlet.*
  • collective.portlets.*
  • collective.*.portlets
  • some vendor-related projects such as “quintagroup.portlet.cumulus”
  • and even projects where “portlet” pattern doesn’t appear in thename.

Even if Plone community has conventions, using the name to categorizedistributions is inappropriate. It’s impossible to get the full list ofdistributions that provide portlets for Plone by filtering on names.But it would be possible if all these distributions used“Framework :: Plone” classifier and “portlet” keyword.

Avoid deep nesting

The Zen of Python says “Flat is better than nested”.

Two levels is almost always enough

Don’t define everything in deeply nested hierarchies: you will end upwith projects and packages like “pythonsport.common.maps.forest”. Thistype of name is both verbose and cumbersome (e.g. if you have manyimports from the package).

Furthermore, big hierarchies tend to break down over time as theboundaries between different packages blur.

The consensus is that two levels of nesting are preferred.

For example, we haveplone.principalsource instead ofplone.source.principal or something like that. The name isshorter, the package structure is simpler, and there would be verylittle to gain from having three levels of nesting here. It would beimpractical to try to put all “core Plone” sources (a source is kindof vocabulary) into theplone.source.* namespace, in part becausesome sources are part of other packages, and in part because sourcesalready exist in other places. Had we made a new namespace, it wouldbe inconsistently used from the start.

Yes: “pyranha”

Yes: “pythonsport.climbing”

Yes: “pythonsport.forestmap”

No: “pythonsport.maps.forest”

Use only one level for ownership

Don’t use 3 levels to set individual/organization ownership ina community namespace.

As an example, let’s consider:

  • you are plugging into a community namespace, such as “collective”.
  • and you want to add a more restrictive “ownership” level, to avoidclashes inside the community.

In such a case,you’d better use the most restrictive ownershiplevel as first level.

As an example, where “collective” is a major community namespace that“gergovie” belongs to, and “vercingetorix” it the name of “gergovie”author:

No: “collective.vercingetorix.gergovie”

Yes: “vercingetorix.gergovie”

Don’t use namespace levels for categorization

Use packaging metadata instead.

Don’t use more than 3 levels

Technically, you can create deeply nested hierarchies. However, inmost cases, you shouldn’t need it.

Note

Even communities where namespaces are standard don’t use more than3 levels.

Conventions for communities or related projects

Follow community or related project conventions, if any

Projects or related communities can have specific conventions, whichmay differ from those explained in this document.

In such a case,they should declare specific conventions indocumentation.

So, if your project belongs to another project or to a community,first look for specific conventions in main project’s documentation.

If there is no specific conventions, follow the ones declared in thisdocument.

As an example,Plone community releases community contributions inthe “collective” namespace package. It differs from thestandardnamespace for contributions proposed here.But since it is documented, there is no ambiguity and you shouldfollow this specific convention.

Use standard pattern for community contributions

When no specific rule is defined, use the${MAINPROJECT}contrib.${PROJECT} pattern to store communitycontributions for any product or framework, where:

  • ${MAINPROJECT} is the name of the related project. “pyranha” inthe example below.
  • ${PROJECT} is the name of your project. “giantteeth” in theexample below.

As an example:

  • you are the author of “pyranha” project. You own the “pyranha”namespace.
  • you didn’t defined specific naming conventions for communitycontributions.
  • a third-party developer wants to publish a “giantteeth” projectrelated to your “pyranha” project in a community namespace. So heshould publish it as “pyranhacontrib.giantteeth”.

It is the simplest way toOrganize community contributions.

Note

Why${MAINPROJECT}contrib.* pattern?

  • ${MAINPROJECT}c.* is not explicit enough. As examples, “zc”belongs to “Zope Corporation” whereas “z3c” belongs to “Zope 3community”.
  • ${MAINPROJECT}community is too long.
  • ${MAINPROJECT}community conflicts with existing namespacessuch as “iccommunity” or “PyCommunity”.
  • ${MAINPROJECT}.contrib.* is inside ${MAINPROJECT} namespace,i.e. it is owned by ${MAINPROJECT} authors. It breaks theTop-level namespace relates to code ownership rule.
  • ${MAINPROJECT}.contrib.* breaks theAvoid deep nestingrule.
  • names where${MAINPROJECT} doesn’t appear are not explicitenough, i.e. nobody can guess they are related to${MAINPROJECT}. As an example, it is not obvious that“collective.*” belongs to Plone community.
  • {$DIST}contrib.* looks like existingsphinxcontrib-*packages. Butsphinxcontrib-* is actually about Sphinxcontrib, so this is not a real conflict… In fact, the “contrib”suffix was inspired by “sphinxcontrib”.

Organize community contributions

This is the counterpart of thefollow community conventions andstandard pattern for contributions rules.

Actions:

  • Choose a naming convention for community contributions.
  • If it is notthe default, thendocument it.
    • if you use thedefault convention, then thisdocument should be enough. Don’t repeat it. You may referenceit.
    • else, tell users about custom conventions in project’s“contribute” or “create modules” documentation.
  • Also recommend the use of additional metadata, such asclassifiers and keywords.

About convention choices:

  • New projects should choose thedefault contrib pattern.
  • Existing projects with community contributions should start withcustom conventions. Then they canPromote migrations.

    It means that existing community conventions don’t have to bechanged. But, at least, they should be explicitly documented.

Example: “pyranha” is your project name and package name.Tell contributors that:

  • pyranha-related distributions should use the “pyranha” keyword
  • pyranha-related distributions providing templates should also use“templates” keyword.
  • community contributions should be released under “pyranhacontrib”namespace (i.e. use “pyranhacontrib.*” pattern).

Register names with PyPI

PyPI is the central place for distributions in Python community.So, it is also the place where to register project and package names.

SeeRegistering with the Package Index for details.

Recipes

The following recipes will help you follow the guidelines andconventions above.

How to check for name availability?

Before you choose a project name, make sure it hasn’t already beenregistered in the following locations:

  • PyPI
  • that’s all. PyPI is the only official place.

As an example, you could also check in various locations such aspopular code hosting services, but keep in mind that PyPI is the onlyplace you canregister for names in Python community.

That’s why it is important youregister names with PyPI.

Also make sure the names of distributed packages or modules haven’talready been registered:

Theuse a single name rule also helps you avoid clashes withpackage names: if a project name is available, then the package namehas good chances to be available too.

How to rename a project?

Renaming a project is possible, but keep in mind that it will causesome confusions. So, pay particular attention to README anddocumentation, so that users understand what happened.

  1. First of all,do not remove legacy distributions from PyPI.Because some users may be using them.
  2. Copy the legacy project, then change names (project andpackage/module). Pay attention to, at least:
    • packaging files,
    • folder name that contains source files,
    • documentation, including README,
    • import statements in code.
  3. AssignObsoletes-Dist metadata to new distribution in setup.cfgfile. SeePEP 345 about Obsolete-Distandsetup.cfgspecification.
  4. Release a new version of the renamed project, then publish it.
  5. Edit legacy project:
    • add dependency to new project,
    • drop everything except packaging stuff,
    • add theDevelopmentStatus::7-Inactive classifier insetup script,
    • publish a new release.

So, users of the legacy package:

  • can continue using the legacy distributions at a deprecated version,
  • can upgrade to last version of legacy distribution, which isempty…
  • … and automatically download new distribution as a dependency ofthe legacy one.

Users who discover the legacy project see it is inactive.

Improved handling of renamed projects on PyPI

If many projects followRenaming howtorecipe, then many legacy distributions will have the followingcharacteristics:

  • DevelopmentStatus::7-Inactive classifier.
  • latest version is empty, except packaging stuff.
  • latest version “redirects” to another distribution. E.g. it has asingle dependency on the renamed project.
  • referenced asObsoletes-Dist in a newer distribution.

So it will be possible to detect renamed projects and improvereadability on PyPI. So that users can focus on active distributions.But this feature is not required now. There is no urge. It won’t becovered in this document.

How to apply naming guidelines on existing projects?

There is no obligation for existing projects to be renamed. Thechoice is left to project authors and mainteners for obvious reasons.

However, project authors are invited to:

State about current naming

The important thing, at first, is that you state about currentchoices:

  • Ask yourself “why did I choose the current name?”, then document it.
  • If there are differences with the guidelines provided in thisdocument, you should tell your users.
  • If possible, create issues in the project’s bugtracker, at least forrecord. Then you are free to resolve them later, or maybe mark themas “wontfix”.

Projects that are meant to receive contributions from community shouldalsoorganize community contributions.

Promote migrations

Every Python developer should migrate whenever possible, or promotethe migrations in their respective communities.

Apply these guidelines on your projects, then the community will seeit is safe.

In particular, “leaders” such as authors of popular projects areinfluential, they have power and, thus, responsibility overcommunities.

Apply these guidelines on popular projects, then communities willadopt the conventions too.

Projects should promote migrations when they release a new (major)version, particularlyif this version introduces support forPython 3.x, new standard library’s packaging or namespace packages.

Opportunity

As of Python 3.3 being developed:

  • many projects are not Python 3.x compatible. It includes “big”products or frameworks. It means that many projects will have to doa migration to support Python 3.x.
  • packaging (aka distutils2) is on the starting blocks. When it isreleased, projects will be invited to migrate and use new packaging.
  • PEP 420 brings official support of namespace packages to Python.

It means that most active projects should be about to migrate in thenext year(s) to support Python 3.x, new packaging or new namespacepackages.

Such an opportunity is unique and won’t come again soon!So let’s introduce and promote naming conventions as soon as possible(i.e.now).

References

Additional background:

References and footnotes:

Copyright

This document has been placed in the public domain.


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

Last modified:2025-05-03 18:09:21 GMT


[8]ページ先頭

©2009-2025 Movatter.jp