Skip to main content

1675. gopy bool and singletons

What we are porting

  • Objects/boolobject.c (~250 lines). bool is a subtype of int with exactly two singleton instances (True, False). Most slots inherit from int; only repr, str, __and__, __or__, __xor__ override.
  • The None singleton from Objects/object.c. Type NoneType, one instance, repr 'None', hash 0.
  • The NotImplemented singleton. Type NotImplementedType, one instance, repr 'NotImplemented', used as a richcompare / binop fallback signal.
  • Ellipsis (the ... literal) lives here for symmetry.

Go shape

// Bool mirrors PyBool_Type. Lives in objects.True / objects.False.
type Bool struct {
Long // embed long; bool is a subtype of int
}

// None is the NoneType singleton.
var None = &noneSingleton{}
type noneSingleton struct { Header }

// NotImplemented is the NotImplementedType singleton.
var NotImplemented = &notImplementedSingleton{}

// Ellipsis is the Ellipsis singleton.
var Ellipsis = &ellipsisSingleton{}

True and False carry the int values 1 and 0 respectively. type(True) == bool, bool.__mro__ == (bool, int, object).

Singleton identity

The constructor Bool(b) returns either True or False. Never constructs a new *Bool. Same rule for NoneType() (always returns None) and NotImplementedType().

Bitwise ops on bool

True & True, True | False, True ^ False return bool, not int, when both operands are bool. CPython 3.0+ rule. Falls back to int arithmetic if either operand is not bool.

File mapping

C sourceGo target
Objects/boolobject.cobjects/bool.go
Objects/object.c:_Py_NoneStructobjects/none.go
Objects/object.c:_Py_NotImplementedStructobjects/notimplemented.go
Objects/sliceobject.c:Py_Ellipsisobjects/ellipsis.go (cross-listed in 1682)

Checklist

Status legend: [x] shipped, [ ] pending, [~] partial / scaffold, [n] deferred / not in scope this phase.

Files

  • [~] objects/bool.go: Bool struct embedding Long, True, False package vars, BoolFromBool(b bool). v0.2 placeholder shipped.
  • [~] objects/none.go: None singleton, NoneType, repr/hash/bool.
  • objects/notimplemented.go: NotImplemented singleton.
  • objects/ellipsis.go: Ellipsis singleton.
  • objects/bool_test.go: identity test for True/False, bitwise narrowing, MRO check.

Surface guarantees

  • True is True, False is False, None is None, NotImplemented is NotImplemented across every constructor / protocol path.
  • bool.__mro__ == (bool, int, object).
  • True & False is False, True | False is True, True ^ True is False (bool, not int).
  • True + 1 == 2 (falls through to int arithmetic).
  • repr(True) == 'True', repr(None) == 'None', repr(NotImplemented) == 'NotImplemented', repr(Ellipsis) == 'Ellipsis'.
  • hash(False) == 0, hash(True) == 1, hash(None) == 0.
  • bool('') is False, bool('x') is True, bool(None) is False.

Out of scope

  • User-subclassable bool. CPython forbids subclassing bool; we honour the same Py_TPFLAGS_BASETYPE clear bit.