Skip to content

[Previous 贡献者 Response Needed] Transition python-zeroconf to the Apache-2.0 License #1835

Description

@bdraco

We plan to migrate python-zeroconf from LGPL-2.1-or-later to Apache 2.0, as requested in #1123. To do this we need every contributor's permission to relicense their contributions.

If you are a contributor, please respond to this issue with something along the lines of:

I consent to my contributions to the python-zeroconf repository being relicensed under Apache 2.0 in place of the current LGPL license.

(Future contributions will simply be made under the repository's Apache 2.0 license, as with any permissively licensed project; no ongoing obligation is created by consenting here.)

I'd also recommend turning off notifications afterwards so GH does not needlessly ping you!

pyzeroconf heritage

python-zeroconf exists thanks to pyzeroconf, created by Paul Scott-Murphy in 2003 and carried forward by William McBrine. This project would not be here without their work, and their names will stay in the project's history and acknowledgements regardless of the license. An initial git blame line audit understated what survives from that era; blame credits whoever moved code in the 2021 package split. An expanded audit with move and copy detection, run after @wmcbrine's comment below, found that a meaningful amount of Paul's 2009 expression was still in the tree, mostly docstrings, so he was added to the table. After both declined, all of that expression was removed and rewritten through successive rounds of progressively stronger audits (blame, move aware blame, word n-grams, character level, fuzzy paraphrase, block level, AST structure, exact whole unit, arrangement comparison, and an independent adversarial re-audit); the removal history below lists every round. The original line by line findings are preserved in the expanded audit sections as a historical record.

We thank Paul Scott-Murphy, William McBrine, and Michał Górny for their historical contributions to the earlier LGPL licensed versions. (A fourth contributor was originally named here and asked not to be attributed; that request is honored.) Their work has been removed from the current tree and will not be part of any Apache licensed release. This acknowledgement is a thank you, not an implication of consent to relicensing.

贡献者

Below is a list of contributors sorted by their active lines of code in the current tree. Note that trivial changes (e.g. bumping a dependency pin or fixing a typo) are generally not copyrightable and would not require consent. For now we are tracking all contributors with surviving lines regardless; if we don't hear back from someone, we will evaluate their actual contributions case by case. 贡献者 whose code no longer appears in the current tree, and bot accounts (pre-commit autofixes, dependency pins, release automation), are not listed.

Contributor Active lines Consent
@bdraco 27,694
@Rotzbua 412
@agners 339
@jstasiak 293
@paulsm 0* declined; all surviving expression removed and rewritten, see removal history and expanded audit below
@apworks1 80
@bboe 71
@Tenebrosus3141 68
@azogue 64
@ibygrave 46
@dtantsur 45
@stephenrauch 42
@cdce8p 25
@che0 19
@smcv 16
@stevencrader 10
@jpbede 8
@jacobtomlinson 8
@ZLJasonG 5
@scop 5
@mattsaxon 5
@gjbadros 3
@wmcbrine 0* declined; all surviving expression removed and rewritten, see removal history and expanded audit below
@bachp 2
@rima1881 2
@Pack3tL0ss 1
@eshattow 0* defers to @wmcbrine; riscv64 wheel work reverted in #1841, workflow step names removed in #1852; only the two mechanical ref: expression fragments itemized in the expanded audit remain
@mgorny 0 declined; his two contributions, a six line sdist include block and one Cython parameter type, are uncopyrightable configuration and type annotations; #1838 reverted them and #1839 re-added the include list re-keyed and the type annotation as written, since a one token type declaration has exactly one spelling

* zero surviving copyrightable lines, not zero blame attributed lines: move and copy aware blame attributes 52 non blank single statement code lines to the pyzeroconf authors at HEAD (some itemized mechanical lines now blame to later commits because the delete and re-add rounds moved attribution; the itemized lists in the expanded audits remain the authoritative inventory) (RFC constant assignments, attribute stores, bare raises, flag mask returns) plus the LGPL text in COPYING, every one itemized in the expanded audits below as retained non expression, so the number a reader's own blame produces matches the number written here. The original line audit missed code that moved in the 2021 package split, which is why these rows carry expanded audits at all.

Removal history

Twelve removal rounds plus a confirming independent re-audit (click to expand)

Twelve removal rounds plus a confirming independent re-audit, each driven by a stronger audit than the last; deletions landed in revert PRs (three of them carried a handful of incidental insertion lines) and every replacement was freshly written and verified against the originals:

  1. revert: drop riscv64 wheel builds #1841 reverted the riscv64 wheel work (eshattow); chore: delete tests and examples containing non-consented work #1842 deleted the affected tests and examples
  2. revert: remove non-consented prose and code from the library #1843 deleted the blame attributed prose and code, chore: restore behavior with freshly authored replacements #1844 replaced the behavior with fresh code
  3. revert: remove derivative prose from the pyzeroconf era #1847 deleted derivative docstrings that blame had misattributed to later editors, found by a blame independent n-gram audit; chore: add freshly written docstrings and async examples #1848 replaced them and recreated the two async examples
  4. revert: remove wmcbrine's readme fork note and six short derivative docstrings #1849 deleted the readme fork note and six short docstrings (four caught by the audit plus two pattern echoes); revert: remove prose echoing pyzeroconf sentence patterns #1851 deleted sentence pattern echoes; chore: fresh docstrings for the short-prose sites and readme rewords #1850 added the fresh replacements
  5. revert: remove short prose found by the character level audit #1852 deleted prose caught by a character level audit (four word class docstrings, test helper docstrings, a zunittest test string, workflow step names); chore: fresh docstrings, test name string and workflow step names #1853 replaced them
  6. revert: remove prose found by the fuzzy paraphrase audit #1854 deleted lines caught by a fuzzy paraphrase audit (production send docstrings, unregister docstrings, the remaining equality family); chore: fresh docstrings for the fuzzy audit sites #1855 replaced them
  7. revert: remove two docstrings echoing 2009 phrasing #1856 deleted two docstrings caught by a block level audit; chore: fresh docstrings for the block audit sites #1857 replaced them; an AST structure comparison found no structural matches in src/ (its coverage of tests/ was incomplete; see round 12)
  8. revert: remove short verbatim prose caught by the whole unit audit #1858 deleted the two to four word verbatim docstrings caught by an exact whole unit audit with no length floor (accessor and entry docstrings, the unregister and listener family, the packets docstring); chore: fresh docstrings for the whole unit audit sites #1859 replaced them (an arrangement claim originally made here was later found to rest on a broken comparison and is corrected in round 12)
  9. a ninth audit of string literals and identifier names found nothing further in src/; the shared names there are the public API classes and RFC constant names, uncopyrightable short phrases and load bearing API surface (four 2009 test class names it missed were retired in round 12)
  10. revert: remove the legacy license banner from every module #1860 removed the legacy 21 line banner from all 36 modules (the v0.14-wmcbrine title, the vestigial 2003/2014 copyright line, the original description prose, and the FSF boilerplate) and chore: add a short license header pointing at COPYING #1861 replaced it with a short LGPL header pointing at COPYING; with the banner gone the prose audits run with no exclusions and report zero shared five word prose runs with any pyzeroconf era blob; five word runs in code lines remain and are the mechanical matches documented in the expanded audits
  11. a 30 character audit over every tracked file, including the pxd files and changelog earlier passes skipped, found one last derivative docstring, removed in revert: remove a derivative notify docstring #1862 and replaced in chore: fresh docstring for notify_all #1863; every other match classified as mechanical, factual attribution, or the project name phrase
  12. an independent adversarial audit of all the claims above found that Paul's 2009 ZeroconfTest.py survived as a mechanically modernized port in test_init, test_protocol and test_core (same class names, method sequence, fixtures and assertions; blame lost the lineage at the 2021 test split, and the earlier structural audits did not cover tests). revert: remove the modernized port of the 2009 test suite #1865 deleted sixteen test methods whole (the eleven the audit scored plus five sibling methods in the same 2009 descended families) and chore: fresh bare pytest tests, de-classed suites and new fixture values #1866 replaced the coverage with freshly authored bare pytest functions, retired the 2009 class names by converting the surviving class based tests to bare functions, and replaced the 2009 descended fixture values across the whole suite. The same audit corrected three earlier overclaims, reflected above: the working method order comparison shows DNSRecord and DNSOutgoing keep substantially the 2009 public method order and _dns.py keeps the 2009 class order, which is API surface and ordering rather than prose, noted here for transparency
  13. the independent auditor re-ran all eight of their audits against the round 12 tree and confirmed the revision holds: none of the 2009 test suite's def or class names remain (the public API class and exception names remain deliberately, per round 9: uncopyrightable short phrases and load bearing API surface), the ported fixtures are at zero occurrences, and the fresh tests are non derivative. Since that re-audit: chore: order classes and methods by the repo convention #1867 reordered the classes and methods to a stated deterministic convention; by the third audit's reproducible metric (ordered LCS over shared snake cased method names) DNSRecord went 1.00 to 0.78 and DNSOutgoing 1.00 to 0.67, and the _dns.py class order went 8/8 to 7/8 shared name LCS, with the residual overlap being the alphabetical rule coinciding with 2009's near alphabetical layout; chore: refresh the stale package author and maintainer metadata #1868 refreshed the stale __author__ and __maintainer__ metadata; chore: replace the remaining 2009 era path fixture values #1869 replaced the remaining 2009 era path fixture values in the tests. A third independent re-audit against that tree confirmed all three PRs hold as described, with zero shared def or class names and only mechanical single statement matches remaining
  14. a second independent adversarial audit, run with a wider corpus (every intermediate pyzeroconf blob), confirmed every removal round as real and surfaced the last blind spots of blame driven scoping: two 2021 example files carrying wmcbrine's 2014 display block by copy paste, the readme usage example descended from the 2009 Browser.py, and the arbitrary DNSText repr truncation, all deleted whole in revert: remove examples and repr inherited from the 2014 browser example #1872 and replaced brand new in chore: brand new async examples, fresh readme example and DNSText repr #1873; the ordering convention was extended to the remaining large classes in chore: extend the ordering convention to the remaining large classes #1874; by the same third audit metric Zeroconf went 1.00 to 0.42, ServiceInfo 1.00 to 0.75 and DNSCache 1.00 to 0.75, while DNSIncoming and ServiceBrowser keep their two to three shared names in coincidental rule generated order

On replacement docstrings: five one sentence replacements measure 0.62 to 0.81 similarity to the sentence they replaced. A docstring that accurately names the fields a method compares can only be phrased so many ways; the position taken here is that such functional one liners are unprotectable however phrased, and the similarity is disclosed rather than claimed away. Retained as non expression and disclosed likewise: the const.py scalar constant block in numeric order (numeric order is the canonical arrangement of RFC values), the import zeroconf as r idiom and the Unit tests for zeroconf.X docstring template across the test suite, and the compelled API surface itemized in the expanded audits.

  1. a third independent audit re-derived every claim from the object store, confirming the prose removal, the revert fidelity and the test rewrite, and correcting the overstatements now fixed above; it surfaced the last structural port, the record display family in _dns.py whose hdr[type,class,name] layout, ?(x) fallback and ttl/remaining prefix reproduce the 2009 toString family, removed whole in revert: remove the 2009 record display formats #1878 and replaced with a fresh angle bracket format in chore: fresh record display formats #1880, along with a 2021 comment paraphrase in the name compressor; the five surviving testname fixture stems it caught were replaced in chore: replace the last testname fixture stems #1881. Retained and disclosed per its inventory: the generated and parsed test variable idiom (a naming convention, not expression) and the compelled identifier surface

All rounds through fifteen are merged or in review. Every finding from both independent adversarial audits is now either removed from the tree, replaced with rule generated or freshly written material, or disclosed above with the retained rationale; the summary comments on this issue were edited to match what an independent blame run produces.

What remains from that era: the factual attribution line and LGPL statement in the readme (replaced by the relicense itself) and single statement textual matches any implementation would share (including a test double in test_browser.py that re-implements the TTL expiry arithmetic, the same mechanical class as the production formula). The __author__ metadata line was refreshed in #1868 and the declaration ordering was regenerated from a stated convention in #1867, so neither remains.

Expanded audits

The two blocks below are the original findings at commit f491259 (the pre squash head of #1839; its tree content landed as 6b2a040, which is where the line links resolve for anyone auditing from a clone), kept as a historical record; every prose line listed has since been removed by the rounds above.

paulsm expanded audit: exact surviving lines (85 prose, 85 textual matches)
wmcbrine expanded audit performed due to non-consent: exact surviving lines (2 prose, 10 edits, 5 header lines)
eshattow expanded audit: 0 surviving prose lines (riscv64 wheel work removed in #1841, workflow step names removed in #1852; only mechanical ref fragments remain)

Metadata

Metadata

Assignees

No one assigned

    标签

    No labels
    No labels

    Type

    No type

    项目

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions