Context
Traits (platforms, architectures, CI systems, shells) currently carry no lifecycle metadata. Some platforms tracked by extra-platforms are discontinued (e.g., Mandriva, Pidora, Scientific Linux), and their URLs already point to archive.org — but there's no structured way to query this status programmatically.
The TODO in trait.py already sketches the idea, referencing PyPI classifiers for long-EOL systems (Windows XP, BeOS, OS/2, PalmOS, etc.) and the endoflife.date project.
Proposal
Add an eol field to the Trait base class representing the date the underlying software reached (or will reach) end of life.
Naming: eol
Considered alternatives:
| Name |
Verdict |
eol |
Chosen. Short, industry-standard acronym. Consistent with terse existing field names (id, url, icon). |
eol_date |
Redundant — the type already communicates it's a date. |
end_of_life |
Too verbose for a frozen dataclass field accessed frequently. |
deprecated |
Wrong semantics — implies the trait object is deprecated in extra-platforms, not that the underlying software is EOL. |
discontinued |
Less standard, conflates "no longer sold" with "no longer supported". |
sunset_date |
Uncommon outside specific corporate contexts. |
Data type: date | None
Considered alternatives:
| Type |
Pros |
Cons |
Verdict |
bool |
Simplest |
Loses when. No future-EOL support. Goes stale silently. |
Rejected |
date | None |
Rich, type-safe. Supports future EOL dates. Enables computed is_eol property. None = actively maintained. |
Requires approximate dates for ancient software with unknown exact EOL. |
Chosen |
str | None |
Flexible (could hold "2001", "2001-06", etc.) |
Not type-safe. Parsing burden. Inconsistent granularity. |
Rejected |
date | bool | None |
Handles "EOL but date unknown" explicitly via True |
Overly complex union type. Awkward to use in conditionals and comparisons. |
Rejected |
For platforms with unknown exact EOL dates (e.g., OS/2, PalmOS), use an approximate date — date(2001, 1, 1) for "discontinued ~2001" is acceptable and keeps the type clean. A docstring note can document this convention.
Placement: Trait base class (not just Platform)
EOL applies across all trait types:
- Platforms: Mandriva (2015), Pidora (2015), Scientific Linux (2019), CentOS (2024)
- Architectures: IA-64/Itanium (2021), PA-RISC, Alpha — all discontinued
- CI systems: Travis CI is commercially dead for OSS
- Shells: csh is effectively superseded
Placing it on Trait keeps the data model uniform and avoids needing to add it later to subclasses one by one.
Computed property: is_eol
Add a computed property for convenience:
@property
def is_eol(self) -> bool:
"""Whether this trait has reached end of life."""
if self.eol is None:
return False
return self.eol <= date.today()
This enables both:
- Retrospective queries: "is this platform EOL?" →
MANDRIVA.is_eol
- Prospective queries: "when does Ubuntu 24.04 go EOL?" →
UBUNTU_2404.eol
- Filtering:
[p for p in ALL_PLATFORMS if not p.is_eol]
Field definition
from datetime import date
@dataclass(frozen=True)
class Trait(_Identifiable, ABC):
eol: date | None = field(repr=False, default=None)
"""End-of-life date of the underlying software.
:data:`None` means the software is actively maintained (or the EOL date is
not yet known). A :class:`~datetime.date` value indicates when the software
reached (or will reach) end of life.
.. note::
For software with imprecise EOL dates, an approximate date is used
(typically January 1st of the known year).
"""
Integration points
generate_docstring(): Include EOL status in auto-generated trait docs (e.g., "EOL: 2015-03-01" or "Active").
info(): Add eol to the info dict returned by all traits.
_base_info(): Include "eol": self.eol.isoformat() if self.eol else None.
- Documentation: Render EOL badges or annotations in the Sphinx-generated trait tables.
- Changelog / Readme: Document the new field.
Data sources
- endoflife.date for well-known platforms
- Wikipedia and vendor announcements for others
archive.org URLs already in the codebase hint at discontinued software
Out of scope (for now)
- Version-specific EOL tracking: Current traits are mostly umbrella names (e.g.,
MACOS, WINDOWS). Tracking per-version EOL (e.g., "macOS 12 Monterey → EOL 2024-09-16") would require a different data model. This proposal covers the trait-level EOL only.
- Active support vs. EOL distinction: Some projects differentiate "active support end" from "extended support end". This proposal uses a single date for simplicity — the final EOL date.
- Automated staleness checks: CI jobs that warn when an EOL date has passed could be useful but are a separate concern.
Context
Traits (platforms, architectures, CI systems, shells) currently carry no lifecycle metadata. Some platforms tracked by extra-platforms are discontinued (e.g., Mandriva, Pidora, Scientific Linux), and their URLs already point to
archive.org— but there's no structured way to query this status programmatically.The TODO in
trait.pyalready sketches the idea, referencing PyPI classifiers for long-EOL systems (Windows XP, BeOS, OS/2, PalmOS, etc.) and the endoflife.date project.Proposal
Add an
eolfield to theTraitbase class representing the date the underlying software reached (or will reach) end of life.Naming:
eolConsidered alternatives:
eolid,url,icon).eol_dateend_of_lifedeprecateddiscontinuedsunset_dateData type:
date | NoneConsidered alternatives:
booldate | Noneis_eolproperty.None= actively maintained.str | None"2001","2001-06", etc.)date | bool | NoneTrueFor platforms with unknown exact EOL dates (e.g., OS/2, PalmOS), use an approximate date —
date(2001, 1, 1)for "discontinued ~2001" is acceptable and keeps the type clean. A docstring note can document this convention.Placement:
Traitbase class (not justPlatform)EOL applies across all trait types:
Placing it on
Traitkeeps the data model uniform and avoids needing to add it later to subclasses one by one.Computed property:
is_eolAdd a computed property for convenience:
This enables both:
MANDRIVA.is_eolUBUNTU_2404.eol[p for p in ALL_PLATFORMS if not p.is_eol]Field definition
Integration points
generate_docstring(): Include EOL status in auto-generated trait docs (e.g., "EOL: 2015-03-01" or "Active").info(): Addeolto the info dict returned by all traits._base_info(): Include"eol": self.eol.isoformat() if self.eol else None.Data sources
archive.orgURLs already in the codebase hint at discontinued softwareOut of scope (for now)
MACOS,WINDOWS). Tracking per-version EOL (e.g., "macOS 12 Monterey → EOL 2024-09-16") would require a different data model. This proposal covers the trait-level EOL only.