-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
pep-0639.rst
904 lines (661 loc) · 38.7 KB
/
pep-0639.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
PEP: 639
Title: Metadata for Python Software Packages 2.2
Version: $Revision$
Last-Modified: $Date$
Author: Philippe Ombredanne <pombredanne at nexb.com>
Sponsor: Paul Moore <p.f.moore at gmail.com>
BDFL-Delegate: Paul Moore <p.f.moore at gmail.com>
Discussions-To: https://discuss.python.org/t/2154
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 15-Aug-2019
Python-Version: 3.x
Post-History:
Replaces: 566
Resolution:
Abstract
========
This PEP describes the changes between versions 2.1 and 2.2 of the `Core
Metadata Specification` [#cms]_ for Python packages. Version 2.1 is specified in
PEP 566.
The primary change introduced in this PEP updates how licenses are documented in
core metadata via the ``License`` field with license expression strings using
SPDX license identifiers [#spdxlist]_ such that license documentation is simpler
and less ambiguous:
- for package authors to create,
- for package users to read and understand, and,
- for tools to process package license information mechanically.
The other changes include:
- specifying a ``License-File`` field which is already used by ``wheel`` and
``setuptools`` to include license files in built distributions.
- defining how tools can validate license expressions and report warnings to
users for invalid expressions (but still accept any string as ``License``).
Goals
=====
This PEP's scope is limited strictly to how we document the license of a
distribution:
- with an improved and structured way to document a license expression, and,
- by including license texts in a built package.
The core metadata specification updates that are part of this PEP have been
designed to have minimal impact and to be backward compatible with v2.1. These
changes utilize emerging new ways to document licenses that are already in use
in some tools (e.g. by adding the ``License-File`` field already used in
``wheel`` and ``setuptools``) or by some package authors (e.g. storing an SPDX
license expression in the existing ``License`` field).
In addition to an update to the metadata specification, this PEP contains:
- recommendations for publishing tools on how to validate the ``License`` and
``Classifier`` fields and report informational warnings when a package uses an
older, non-structured style of license documentation conventions.
- informational appendices that contain surveys of how we document licenses
today in Python packages and elsewhere, and a reference Python library to
parse, validate and build correct license expressions.
It is the intent of the PEP authors to work closely with tool authors to
implement the recommendations for validation and warnings specified in this PEP.
Non-Goals
=========
This PEP is neutral regarding the choice of license by any package author.
In particular, the SPDX license expression syntax proposed in this PEP provides
simpler and more expressive conventions to document accurately any kind of
license that applies to a Python package, whether it is an open source license,
a free or libre software license, a proprietary license, or a combination of
such licenses.
This PEP makes no recommendation for specific licenses and does not require the
use of specific license documentation conventions. This PEP also does not impose
any restrictions when uploading to PyPI.
Instead, this PEP is intended to document common practices already in use, and
recommends that publishing tools should encourage users via informational
warnings when they do not follow this PEP's recommendations.
This PEP is not about license documentation in files inside packages, even
though this is a surveyed topic in the appendix.
Possible future PEPs
--------------------
It is the intention of the authors of this PEP to consider the submission of
related but separate PEPs in the future such as:
- make ``License`` and new ``License-File`` fields mandatory including
stricter enforcement in tools and PyPI publishing.
- require uploads to PyPI to use only FOSS (Free and Open Source software)
licenses.
Motivation
==========
Software is licensed, and providing accurate licensing information to Python
packages users is an important matter. Today, there are multiple places where
licenses are documented in package metadata and there are limitations to what
can be documented. This is often leading to confusion or a lack of clarity both
for package authors and package users.
Several package authors have expressed difficulty and/or frustrations due to the
limited capabilities to express licensing in package metadata. This also applies
to Linux and BSD* distribution packagers. This has triggered several
license-related discussions and issues, in particular:
- https://github.com/pypa/trove-classifiers/issues/17
- https://github.com/pypa/interoperability-peps/issues/46
- https://github.com/pypa/packaging-problems/issues/41
- https://github.com/pypa/wheel/issues/138
- https://github.com/pombredanne/spdx-pypi-pep/issues/1
On average, Python packages tend to have more ambiguous, or missing, license
information than other common application package formats (such as npm, Maven or
Gem) as can be seen in the statistics [#cdstats]_ page of the ClearlyDefined
[#cd]_ project that cover all packages from PyPI, Maven, npm and Rubygems.
ClearlyDefined is an open source project to help improve clarity of other open
source projects that is incubating at the OSI (Open Source Initiative) [#osi]_.
Rationale
=========
A mini-survey of existing license metadata definitions in use in the Python
ecosystem today and documented in several other system/distro and application
package formats is provided in Appendix 2 of this PEP.
There are a few takeaways from the survey:
- Most package formats use a single ``License`` field.
- Many modern package formats use some form of license expression syntax to
optionally combine more than one license identifier together. SPDX and
SPDX-like syntaxes are the most popular in use.
- SPDX license identifiers are becoming a de facto way to reference common
licenses everywhere, whether or not a license expression syntax is used.
- Several package formats support documenting both a license expression and the
paths of the corresponding files that contain the license text. Most free and
open source software licenses require package authors to include their full
text in a distribution.
These considerations have guided the design and recommendations of this PEP.
The reuse of the ``License`` field with license expressions will provide an
intuitive and more structured way to express the license of a distribution using
a well-defined syntax and well-known license identifiers.
Over time, recommending the usage of these expressions will help Python package
publishers improve the clarity of their license documentation to the benefit of
package authors, consumers and redistributors.
Core Metadata Specification updates
===================================
The canonical source for the names and semantics of each of the supported
metadata fields is the Core Metadata Specification [#cms]_ document.
The details of the updates considered to the Core Metadata Specification [#cms]_
document as part of this PEP are described here and will be added to the
canonical source once this PEP is approved.
Added in Version 2.2
--------------------
License-File (multiple use)
:::::::::::::::::::::::::::
The License-File is a string that is a path, relative to``.dist-info``, to a
license file. The license file content MUST be UTF-8 encoded text.
Build tools SHOULD honor this field and include the corresponding license
file(s) in the built package.
Changed in Version 2.2
----------------------
License (optional)
::::::::::::::::::
Text indicating the license covering the distribution. This text can be either a
valid license expression as defined here or any free text.
Publishing tools SHOULD issue an informational warning if this field is empty,
missing, or is not a valid license expression as defined here. Build tools MAY
issue a similar warning.
License Expression syntax
'''''''''''''''''''''''''
A license expression is a string using the SPDX license expression syntax as
documented in the SPDX specification [#spdx]_ using either Version 2.2
[#spdx22]_ or a later compatible version. SPDX is a working group at the Linux
Foundation that defines a standard way to exchange package information.
When used in the ``License`` field and as a specialization of the SPDX license
expression definition, a license expression can use the following license
identifiers:
- any SPDX-listed license short-form identifiers that are published in the SPDX
License List [#spdxlist]_ using either Version 3.10 or any later compatible
version. Note that the SPDX working group never removes any license
identifiers: instead they may choose to mark an identifier as "deprecated".
- the ``LicenseRef-Public-Domain`` and ``LicenseRef-Proprietary`` strings to
identify licenses that are not included in the SPDX license list.
When processing the ``License`` field to determine if it contains a valid
license expression, tools:
- SHOULD report an informational warning if one or more of the following
applies:
- the field does not contain a license expression,
- the license expression syntax is invalid,
- the license expression syntax is valid but some license identifiers are
unknown as defined here or the license identifiers have been marked as
deprecated in the SPDX License List [#spdxlist]_
- SHOULD store a case-normalized version of the ``License`` field using the
reference case for each SPDX license identifier and uppercase for the AND, OR
and WITH keywords.
- SHOULD report an informational warning if normalization process results in
changes to the ``License`` field contents.
License expression examples::
License: MIT
License: BSD-3-Clause
License: MIT OR GPL-2.0-or-later OR (FSFUL AND BSD-2-Clause)
License: GPL-3.0-only WITH Classpath-Exception-2.0 OR BSD-3-Clause
License: This software may only be obtained by sending the
author a postcard, and then the user promises not
to redistribute it.
License: LicenseRef-Proprietary AND LicenseRef-Public-Domain
Classifier (multiple use)
:::::::::::::::::::::::::
Each entry is a string giving a single classification value for the
distribution. Classifiers are described in PEP 301.
Examples::
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console (Text Based)
Tools SHOULD issue an informational warning if this field contains a licensing-
related classifier string starting with the ``License ::`` prefix and SHOULD
suggest the use of a license expression in the ``License`` field instead.
If the ``License`` field is present and contains a valid license expression,
publishing tools MUST NOT also provide any licensing-related classifier entries
[#classif]_.
However, for compatibility with existing publishing and installation processes,
licensing-related classifier entries SHOULD continue to be accepted if the
``License`` field is absent or does not contain a valid license expression.
Publishing tools MAY infer a license expression from the provided classifier
entries if they are able to do so unambiguously.
However, no new licensing related classifiers will be added; anyone
requesting them will be directed to use a license expression in the ``License``
field instead. Note that the licensing-related classifiers may be deprecated in
a future PEP.
Mapping Legacy Classifiers to New License Expressions
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Publishing tools MAY infer or suggest an equivalent license expression from the
provided ``License`` or ``Classifier`` information if they are able to do so
unambiguously. For instance, if a package only has this license classifier::
Classifier: License :: OSI Approved :: MIT License
Then the corresponding value for a ``License`` field using a valid license
expression to suggest would be::
License: MIT
Here are mapping guidelines for the legacy classifiers:
- Classifier ``License :: Other/Proprietary License`` becomes License:
``LicenseRef-Proprietary`` expression.
- Classifier ``License :: Public Domain`` becomes License: ``LicenseRef-Public-Domain``
expression, though tools should encourage the use of more explicit and legally
portable license identifiers such as ``CC0-1.0`` [#cc0]_, the ``Unlicense``
[#unlic]_ since the meaning associated with the term "public domain" is thoroughly
dependent on the specific legal jurisdiction involved and some jurisdictions
have no concept of Public Domain as it exists in the USA.
- The generic and ambiguous classifiers ``License :: OSI Approved`` and
``License :: DFSG approved`` do not have an equivalent license expression.
- The generic and sometimes ambiguous classifiers
``License :: Free For Educational Use``, ``License :: Free For Home Use``,
``License :: Free for non-commercial use``, ``License :: Freely Distributable``,
``License :: Free To Use But Restricted``, and ``License :: Freeware`` are mapped
to the generic License: ``LicenseRef-Proprietary`` expression.
- Classifiers ``License :: GUST*`` have no mapping to SPDX license identifierss
for now and no package uses them in PyPI as of the writing of this PEP.
The remainder of the classifiers using a ``License ::`` prefix map to a simple
single-identifier license expression using the corresponding SPDX license identifiers.
When multiple license-related classifiers are used, their relation is ambiguous
and it is typically not possible to determine if all the licenses apply or if
there is a choice that is possible among the licenses. In this case, tools
cannot reliably infer a license expression and should suggest that the package
author construct a license expression which expresses their intent.
Summary of Differences From PEP 566
===================================
* Metadata-Version is now 2.2.
* Added one new field: ``License-File``
* Updated the documentation of two fields: ``License`` and ``Classifier``
Backwards Compatibility
=======================
The reuse of the ``License`` field means that we keep backward
compatibility. The specification of the ``License-File`` field is only writing
down the practices of the ``wheel`` and ``setuptools`` tools and is backward
compatible with their support for that field.
The "soft" validation of the ``License`` field when it does not contain a valid
license expression and when the ``Classifier`` field is used with legacy
license-related classifiers means that we can gently prepare users for possible
strict and incompatible validation of these fields in the future.
Security Implications
=====================
This PEP has no foreseen security implications: the License field is a plain
string and the License-File(s) are file paths. None of them introduces any new
security concern.
How to Teach Users to Use License Expressions
=============================================
The simple cases are simple: a single license identifier is a valid license
expression and a large majority of packages use a single license.
The plan to teach users of packaging tools how to express their package's
license with a valid license expression is to have tools issue informative
messages when they detect invalid license expressions or when a license-related
classifier is used in the ``Classifier`` field.
With a warning message that does not terminate processing, publishing tools will
gently teach users how to provide correct license expressions over time.
Tools may also help with the conversion and suggest a license expression in some
cases:
1. The section `Mapping Legacy Classifiers to New License expressions`_ provides
tool authors with guidelines on how to suggest a license expression produced
from legacy classifiers.
2. Tools may also be able to infer and suggest how to update an existing
incorrect ``License`` value and convert that to a correct license expression.
For instance a tool may suggest to correct a ``License`` field from
``Apache2`` (which is not a valid license expression as defined in this PEP)
to ``Apache-2.0`` (which is a valid license expression using an SPDX license
identifier as defined in this PEP).
Reference Implementation
========================
Tools will need to support parsing and validating license expressions in the
``License`` field.
The ``license-expression`` library [#licexp]_ is a reference Python
implementation of a library that handles license expressions including parsing,
validating and formatting license expressions using flexible lists of license
symbols (including SPDX license identifiers and any extra identifiers referenced
here). It is licensed under the Apache-2.0 license and is used in a few projects
such as the SPDX Python tools [#spdxpy]_, the ScanCode toolkit [#scancodetk]_
and the Free Software Foundation Europe (FSFE) Reuse project [#reuse]_.
Rejected ideas
==============
1. Use a new ``License-Expression`` field and deprecate the ``License`` field.
Adding a new field would introduce backward incompatible changes when the
``License`` field would be retired later and require having more complex
validation. The use of such a field would further introduce a new concept that
is not seen anywhere else in any other package metadata (e.g. a new field only
for license expression) and possibly be a source of confusion. Also, users are
less likely to start using a new field than make small adjustments to their use
of existing fields.
2. Mapping licenses used in the license expression to specific files in the
license files (or vice versa).
This would require using a mapping (two parallel lists would be too prone to
alignment errors) and a mapping would bring extra complication to how license
are documented by adding an additional nesting level.
A mapping would be needed as you cannot guarantee that all expressions (e.g.
GPL with an exception may be in a single file) or all the license keys have a
single license file and that any expression does not have more than one. (e.g.
an Apache license ``LICENSE`` and its ``NOTICE`` file for instance are two
distinct files). Yet in most cases, there is a simpler "one license", "one or
more license files". In the rarer and more complex cases where there are many
licenses involved you can still use the proposed conventions at the cost of a
slight loss of clarity by not specifying which text file is for which license
identifier, but you are not forcing the more complex data model (e.g. a mapping)
on everyone that may not need it.
We could of course have a data field with multiple possible value types (it’s a
string, it’s a list, it’s a mapping!) but this could be a source of confusion.
This is what has been done for instance in npm (historically) and in Rubygems
(still today) and as result you need to test the type of the metadata field
before using it in code and users are confused about when to use a list or a
string.
3. Mapping licenses to specific source files and/or directories of source files
(or vice versa).
File-level notices are not considered as part of the scope of this PEP and the
existing ``SPDX-License-Identifier`` [#spdxids]_ convention can be used and
may not need further specification as a PEP.
Appendix 1. License Expression example
======================================
The current version of ``setuptools`` metadata [#setuptools5030]_ does not use
the ``License`` field. It uses instead this license-related information in
``setup.cfg``::
license_file = LICENSE
classifiers =
License :: OSI Approved :: MIT License
The simplest migration to this PEP would consist of using this instead::
license = MIT
license_files =
LICENSE
Another possibility would be to include the licenses of the third-party packages
that are vendored in the ``setuptools/_vendor/`` and ``pkg_resources/_vendor``
directories::
appdirs==1.4.3
packaging==20.4
pyparsing==2.2.1
ordered-set==3.1.1
These license expressions for these packages are::
appdirs: MIT
packaging: Apache-2.0 OR BSD-2-Clause
pyparsing: MIT
ordered-set: MIT
Therefore, a comprehensive license expression covering both ``setuptools`` proper
and its vendored packages could contain these metadata, combining all the
license expressions in one expression::
license = MIT AND (Apache-2.0 OR BSD-2-Clause)
license_files =
LICENSE.MIT
LICENSE.packaging
Here we would assume that the ``LICENSE.MIT`` file contains the text of the MIT
license and the copyrights used by ``setuptools``, ``appdirs``, ``pyparsing`` and
``ordered-set``, and that the ``LICENSE.packaging`` file contains the texts of the
Apache and BSD license, its copyrights and its license choice notice [#packlic]_.
Appendix 2. Surveying how we document licenses today in Python
==============================================================
There are multiple ways used or recommended to document Python package
licenses today:
In Core metadata
----------------
There are two overlapping core metadata fields to document a license: the
license-related ``Classifier`` strings [#classif]_ prefixed with ``License ::`` and
the ``License`` field as free text [#licfield]_.
The core metadata documentation ``License`` field documentation is currently::
License (optional)
::::::::::::::::::
Text indicating the license covering the distribution where the license
is not a selection from the "License" Trove classifiers. See
"Classifier" below. This field may also be used to specify a
particular version of a license which is named via the ``Classifier``
field, or to indicate a variation or exception to such a license.
Examples::
License: This software may only be obtained by sending the
author a postcard, and then the user promises not
to redistribute it.
License: GPL version 3, excluding DRM provisions
Even though there are two fields, it is at times difficult to convey anything
but simpler licensing. For instance some classifiers lack accuracy (GPL
without a version) and when you have multiple License-related classifiers it is
not clear if this is a choice or all these apply and which ones. Furthermore,
the list of available license-related classifiers is often out-of-date.
In the PyPA ``sampleproject``
-----------------------------
The latest PyPA ``sampleproject`` recommends only to use classifiers in
``setup.py`` and does not list the ``license`` field in its example
``setup.py`` [#samplesetup]_.
The License Files in wheels and setuptools
------------------------------------------
Beyond a license code or qualifier, license text files are documented and
included in a built package either implicitly or explicitly and this is another
possible source of confusion:
- In wheels [#wheels]_ license files are automatically added to the ``.dist-info``
directory if they match one of a few common license file name patterns (such
as LICENSE*, COPYING*). Alternatively a package author can specify a list of
license file paths to include in the built wheel using in the
``license_files`` field in the ``[metadata]`` section of the project's
``setup.cfg``. Previously this was a (singular) ``license_file`` file attribute
that is now deprecated but is still in common use. See [#pipsetup]_ for
instance.
- In ``setuptools`` [#setuptoolssdist]_, a ``license_file`` attribute is used to add
a single license file to a source distribution. This singular version is
still honored by ``wheels`` for backward compatibility.
- Using a LICENSE.txt file is encouraged in the packaging guide [#packaging]_
paired with a ``MANIFEST.in`` entry to ensure that the license file is included
in a built source distribution (sdist).
Note: the License-File field proposed in this PEP already exists in ``wheel`` and
``setuptools`` with the same behaviour as explained above. This PEP is only
recognizing and documenting the existing practice as used in ``wheel`` (with the
``license_file`` and ``license_files`` ``setup.cfg`` ``[metadata]`` entries) and in
``setuptools`` ``license_file`` ``setup()`` argument.
In Python code files
--------------------
(Note: Documenting licenses in source code is not in the scope of this PEP)
Beside using comments and/or ``SPDX-License-Identifier`` conventions, the license
is sometimes documented in Python code files using "dunder" variables typically
named after one of the lower cased Core Metadata fields such as ``__license__``
[#pycode]_.
This convention (dunder global variables) is recognized by the built-in ``help()``
function and the standard ``pydoc`` module. The dunder variable(s) will show up in
the ``help()`` DATA section for a module.
In some other Python packaging tools
------------------------------------
- Conda package manifest [#conda]_ has support for ``license`` and ``license_file``
fields as well as a ``license_family`` license grouping field.
- ``flit`` [#flit]_ recommends to use classifiers instead of License (as per the
current metadata spec).
- ``pbr`` [#pbr]_ uses similar data as setuptools but always stored setup.cfg.
- ``poetry`` [#poetry]_ specifies the use of the ``license`` field in
``pyproject.toml`` with SPDX license identifiers.
Appendix 3. Surveying how other package formats document licenses
=================================================================
Here is a survey of how things are done elsewhere.
License in Linux distribution packages
---------------------------------------
Note: in most cases the license texts of the most common licenses are included
globally once in a shared documentation directory (e.g. /usr/share/doc).
- Debian document package licenses with machine readable copyright files
[#dep5]_. This specification defines its own license expression syntax that is
very similar to the SDPX syntax and use its own list of license identifiers
for common licenses (also closely related to SPDX identifiers).
- Fedora packages [#fedora]_ specify how to include ``License Texts``
[#fedoratext]_ and how use a ``License`` field [#fedoralic]_ that must be filled
with an appropriate license Short License identifier(s) from an extensive list
of "Good Licenses" identifiers [#fedoralist]_. Fedora also defines its own
license expression syntax very similar to the SDPX syntax.
- openSUSE packages [#opensuse]_ use SPDX license expressions with
SPDX license identifiers and a list of extra license identifiers
[#opensuselist]_.
- Gentoo ebuild uses a ``LICENSE`` variable [#gentoo]_. This field is specified
in GLEP-0023 [#glep23]_ and in the Gentoo development manual [#gentoodev]_.
Gentoo also defines a license expression syntax and a list of allowed
licenses. The expression syntax is rather different from SPDX.
- FreeBSD package Makefile [#freebsd]_ provides ``LICENSE`` and
``LICENSE_FILE`` fields with a list of custom license symbols. For
non-standard licenses, FreeBSD recommend to use ``LICENSE=UNKNOWN`` and add
``LICENSE_NAME`` and ``LICENSE_TEXT`` fields, as well as sophisticated
``LICENSE_PERMS`` to qualify the license permissions and ``LICENSE_GROUPS``
to document a license grouping. The ``LICENSE_COMB`` allows to document more
than one license and how they apply together, forming a custom license
expression syntax. FreeBSD also recommends the use of
``SPDX-License-Identifier`` in source code files.
- Archlinux PKGBUILD [#archinux]_ define its own license identifiers
[#archlinuxlist]_. The value ``'unknown'`` can be used if the license is not
defined.
- OpenWRT ipk packages [#openwrt]_ use the ``PKG_LICENSE`` and
``PKG_LICENSE_FILES`` variables and recommend the use of SPDX License
identifiers.
- NixOS uses SPDX identifiers [#nixos]_ and some extra license identifiers in
its license field.
- GNU Guix (based on NixOS) has a single License field, uses its own license
symbols list [#guix]_ and specifies to use one license or a list of licenses
[#guixlic]_.
- Alpine Linux packages [#alpine]_ recommend using SPDX identifiers in the
license field.
License in Language and Application packages
--------------------------------------------
- In Java, Maven POM [#maven]_ defines a ``licenses`` XML tag with a list of license
items each with a name, URL, comments and "distribution" type. This is not
mandatory and the content of each field is not specified.
- JavaScript npm package.json [#npm]_ use a single license field with SPDX
license expression or the ``UNLICENSED`` id if no license is specified.
A license file can be referenced as an alternative using "SEE LICENSE IN
<filename>" in the single ``license`` field.
- Rubygems gemspec [#gem]_ specifies either a singular license string or a list
of license strings. The relationship between multiple licenses in a list is
not specified. They recommend using SPDX license identifiers.
- CPAN Perl modules [#perl]_ use a single license field which is either a single
string or a list of strings. The relationship between the licenses in a list
is not specified. There is a list of custom license identifiers plus
these generic identifiers: ``open_source``, ``restricted``, ``unrestricted``,
``unknown``.
- Rust Cargo [#cargo]_ specifies the use of an SPDX license expression (v2.1) in
the ``license`` field. It also supports an alternative expression syntax using
slash-separated SPDX license identifiers. There is also a ``license_file``
field. The crates.io package registry [#cratesio]_ requires that either
``license`` or ``license_file`` fields are set when you upload a package.
- PHP Composer composer.json [#composer]_ uses a ``license`` field with an SPDX
license id or "proprietary". The ``license`` field is either a single string
that can use something which resembles the SPDX license expression syntax with
"and" and "or" keywords; or is a list of strings if there is a choice of
licenses (aka. a "disjunctive" choice of license).
- NuGet packages [#nuget]_ were using only a simple license URL and are now
specifying to use an SPDX License expression and/or the path to a license
file within the package. The NuGet.org repository states that they only
accepts license expressions that are `approved by the Open Source Initiative
or the Free Software Foundation.`
- Go language modules ``go.mod`` have no provision for any metadata beyond
dependencies. Licensing information is left for code authors and other
community package managers to document.
- Dart/Flutter spec [#flutter]_ recommends to use a single ``LICENSE`` file
that should contain all the license texts each separated by a line with 80
hyphens.
- JavaScript Bower [#bower]_ ``license`` field is either a single string or a list
of strings using either SPDX license identifiers, or a path or a URL to a
license file.
- Cocoapods podspec [#cocoapod]_ ``license`` field is either a single string or a
mapping with attributes of type, file and text keys. This is mandatory unless
there is a LICENSE or LICENCE file provided.
- Haskell Cabal [#cabal]_ accepts an SPDX license expression since version 2.2.
The version of the SPDX license list used is a function of the ``cabal`` version.
The specification also provides a mapping between pre-SPDX Legacy license
Identifiers and SPDX identifiers. Cabal also specifies a ``license-file(s)``
field that lists license files that will be installed with the package.
- Erlang/Elixir mix/hex package [#mix]_ specifies a ``licenses`` field as a
required list of license strings and recommends to use SPDX license
identifiers.
- D lang dub package [#dub]_ defines its own list of license identifiers and
its own license expression syntax and both are similar to the SPDX conventions.
- R Package DESCRIPTION [#cran]_ defines its own sophisticated license
expression syntax and list of licenses identifiers. R has a unique way to
support specifiers for license versions such as ``LGPL (>= 2.0, < 3)`` in its
license expression syntax.
Conventions used by other ecosystems
------------------------------------
- ``SPDX-License-Identifier`` [#spdxids]_ is a simple convention to document the
license inside a file.
- The Free Software Foundation (FSF) promotes the use of SPDX license identifiers
for clarity in the GPL and other versioned free software licenses [#gnu]_
[#fsf]_.
- The Free Software Foundation Europe (FSFE) REUSE project [#reuse]_ promotes
using ``SPDX-License-Identifier``.
- The Linux kernel uses ``SPDX-License-Identifier`` and parts of the FSFE REUSE
conventions to document its licenses [#linux]_.
- U-Boot spearheaded using ``SPDX-License-Identifier`` in code and now follows the
Linux ways [#uboot]_.
- The Apache Software Foundation projects use RDF DOAP [#apache]_ with a single
license field pointing to SPDX license identifiers.
- The Eclipse Foundation promotes using ``SPDX-license-Identifiers`` [#eclipse]_
- The ClearlyDefined project [#cd]_ promotes using SPDX license identifiers and
expressions to improve license clarity.
- The Android Open Source Project [#android]_ use ``MODULE_LICENSE_XXX`` empty
tag files where ``XXX`` is a license code such as BSD, APACHE, GPL, etc. And
side by side with this ``MODULE_LICENSE`` file there is a ``NOTICE`` file
that contains license and notices texts.
References
==========
This document specifies version 2.2 of the metadata format.
- Version 1.0 is specified in PEP 241.
- Version 1.1 is specified in PEP 314.
- Version 1.2 is specified in PEP 345.
- Version 2.0, while not formally accepted, was specified in PEP 426.
- Version 2.1 is specified in PEP 566.
.. [#cms] https://packaging.python.org/specifications/core-metadata
.. [#cdstats] https://clearlydefined.io/stats
.. [#cd] https://clearlydefined.io
.. [#osi] http://opensource.org
.. [#classif] https://pypi.org/classifiers
.. [#spdxlist] https://spdx.org/licenses
.. [#spdx] https://spdx.org
.. [#spdx22] https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/
.. [#wheels] https://github.com/pypa/wheel/blob/b8b21a5720df98703716d3cd981d8886393228fa/docs/user_guide.rst#including-license-files-in-the-generated-wheel-file
.. [#reuse] https://reuse.software/
.. [#licexp] https://github.com/nexB/license-expression/
.. [#spdxpy] https://github.com/spdx/tools-python/
.. [#scancodetk] https://github.com/nexB/scancode-toolkit
.. [#licfield] https://packaging.python.org/guides/distributing-packages-using-setuptools/?highlight=MANIFEST.in#license
.. [#samplesetup] https://github.com/pypa/sampleproject/blob/52966defd6a61e97295b0bb82cd3474ac3e11c7a/setup.py#L98
.. [#pipsetup] https://github.com/pypa/pip/blob/476606425a08c66b9c9d326994ff5cf3f770926a/setup.cfg#L40
.. [#setuptoolssdist] https://github.com/pypa/setuptools/blob/97e8ad4f5ff7793729e9c8be38e0901e3ad8d09e/setuptools/command/sdist.py#L202
.. [#packaging] https://packaging.python.org/guides/distributing-packages-using-setuptools/?highlight=MANIFEST.in#license-txt
.. [#pycode] https://github.com/search?l=Python&q=%22__license__%22&type=Code
.. [#setuptools5030] https://github.com/pypa/setuptools/blob/v50.3.0/setup.cfg#L17
.. [#packlic] https://github.com/pypa/packaging/blob/19.1/LICENSE
.. [#conda] https://docs.conda.io/projects/conda-build/en/latest/resources/define-metadata.html#about-section
.. [#flit] https://github.com/takluyver/flit
.. [#poetry] https://poetry.eustace.io/docs/pyproject/#license
.. [#pbr] https://docs.openstack.org/pbr/latest/user/features.html
.. [#dep5] https://dep-team.pages.debian.net/deps/dep5/
.. [#fedora] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
.. [#fedoratext] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_license_text
.. [#fedoralic] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_valid_license_short_names
.. [#fedoralist] https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses
.. [#opensuse] https://en.opensuse.org/openSUSE:Packaging_guidelines#Licensing
.. [#opensuselist] https://docs.google.com/spreadsheets/d/14AdaJ6cmU0kvQ4ulq9pWpjdZL5tkR03exRSYJmPGdfs/pub
.. [#gentoo] https://devmanual.gentoo.org/ebuild-writing/variables/index.html#license
.. [#glep23] https://www.gentoo.org/glep/glep-0023.html
.. [#gentoodev] https://devmanual.gentoo.org/general-concepts/licenses/index.html
.. [#freebsd] https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/licenses.html
.. [#archinux] https://wiki.archlinux.org/index.php/PKGBUILD#license
.. [#archlinuxlist] https://wiki.archlinux.org/index.php/PKGBUILD#license
.. [#openwrt] https://openwrt.org/docs/guide-developer/packages#buildpackage_variables
.. [#nixos] https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix
.. [#guix] http://git.savannah.gnu.org/cgit/guix.git/tree/guix/licenses.scm
.. [#guixlic] https://guix.gnu.org/manual/en/html_node/package-Reference.html#index-license_002c-of-packages
.. [#alpine] https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package#license
.. [#maven] https://maven.apache.org/pom.html#Licenses
.. [#npm] https://docs.npmjs.com/files/package.json#license
.. [#gem] https://guides.rubygems.org/specification-reference/#license=
.. [#perl] https://metacpan.org/pod/CPAN::Meta::Spec#license
.. [#cargo] https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata
.. [#cratesio] https://doc.rust-lang.org/cargo/reference/registries.html#publish
.. [#composer] https://getcomposer.org/doc/04-schema.md#license
.. [#nuget] https://docs.microsoft.com/en-us/nuget/reference/nuspec#licenseurl
.. [#flutter] https://flutter.dev/docs/development/packages-and-plugins/developing-packages#adding-licenses-to-the-license-file
.. [#bower] https://github.com/bower/spec/blob/master/json.md#license
.. [#cocoapod] https://guides.cocoapods.org/syntax/podspec.html#license
.. [#cabal] https://cabal.readthedocs.io/en/latest/developing-packages.html#pkg-field-license
.. [#mix] https://hex.pm/docs/publish
.. [#dub] https://dub.pm/package-format-json.html#licenses
.. [#cran] https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Licensing
.. [#spdxids] https://spdx.org/using-spdx-license-identifier
.. [#gnu] https://www.gnu.org/licenses/identify-licenses-clearly.html
.. [#fsf] https://www.fsf.org/blogs/rms/rms-article-for-claritys-sake-please-dont-say-licensed-under-gnu-gpl-2
.. [#linux] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst
.. [#uboot] https://www.denx.de/wiki/U-Boot/Licensing
.. [#apache] https://svn.apache.org/repos/asf/allura/doap_Allura.rdf
.. [#eclipse] https://www.eclipse.org/legal/epl-2.0/faq.php
.. [#android] https://github.com/aosp-mirror/platform_external_tcpdump/blob/master/MODULE_LICENSE_BSD
.. [#cc0] https://creativecommons.org/publicdomain/zero/1.0/
.. [#unlic] https://unlicense.org/
Copyright
=========
This document is placed in the public domain or under the CC0-1.0-Universal
license [#cc0]_, whichever is more permissive.
Acknowledgements
================
- Nick Coghlan
- Kevin P. Fleming
- Pradyun Gedam
- Oleg Grenrus
- Dustin Ingram
- Chris Jerdonek
- Cyril Roelandt
- Luis Villa
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 80
End: