@@ -1274,8 +1274,8 @@ extension PythonObject : SignedNumeric {
12741274 return self < 0 ? - self : self
12751275 }
12761276
1277- //override the default implementation of - prefix function
1278- //from SignedNumeric (https://bugs.swift.org/browse/SR-13293)
1277+ // Override the default implementation of `-` prefix function
1278+ // from SignedNumeric (https://bugs.swift.org/browse/SR-13293).
12791279 public static prefix func - ( _ operand: Self ) -> Self {
12801280 return performUnaryOp ( PyNumber_Negative, operand: operand)
12811281 }
@@ -1472,8 +1472,36 @@ extension PythonObject : ExpressibleByArrayLiteral, ExpressibleByDictionaryLiter
14721472 }
14731473 public typealias Key = PythonObject
14741474 public typealias Value = PythonObject
1475+
1476+ // Preserves element order in the final Python object, unlike
1477+ // `Dictionary.pythonObject`. When keys are duplicated, throw the same
1478+ // runtime error as `Swift.Dictionary.init(dictionaryLiteral:)`. This
1479+ // differs from Python's key uniquing semantics, which silently override an
1480+ // existing key with the next one it encounters.
14751481 public init ( dictionaryLiteral elements: ( PythonObject , PythonObject ) ... ) {
1476- self . init ( Dictionary ( elements, uniquingKeysWith: { lhs, _ in lhs } ) )
1482+ _ = Python // Ensure Python is initialized.
1483+ let dict = PyDict_New ( ) !
1484+ for (key, value) in elements {
1485+ let k = key. ownedPyObject
1486+ let v = value. ownedPyObject
1487+
1488+ // Use Python's native key checking instead of querying whether
1489+ // `elements` contains the key. Although this could theoretically
1490+ // produce different results, it produces the Python object we want.
1491+ switch PyDict_Contains ( dict, k) {
1492+ case 0 :
1493+ PyDict_SetItem ( dict, k, v)
1494+ case 1 :
1495+ fatalError ( " Dictionary literal contains duplicate keys " )
1496+ default :
1497+ try ! throwPythonErrorIfPresent ( )
1498+ fatalError ( " No result or error checking whether \( elements) contains \( key) " )
1499+ }
1500+
1501+ Py_DecRef ( k)
1502+ Py_DecRef ( v)
1503+ }
1504+ self . init ( consuming: dict)
14771505 }
14781506}
14791507
@@ -1876,7 +1904,9 @@ public struct PythonClass {
18761904 ( key, value. pythonObject)
18771905 }
18781906
1879- dictionary = Dictionary ( castedElements, uniquingKeysWith: { lhs, _ in lhs } )
1907+ dictionary = Dictionary ( castedElements, uniquingKeysWith: { _, _ in
1908+ fatalError ( " Dictionary literal contains duplicate keys " )
1909+ } )
18801910 }
18811911 }
18821912
0 commit comments