Skip to content

[Stdlib] Add Comparable conformance to Path#6170

Open
msaelices wants to merge 3 commits intomodular:mainfrom
msaelices:feat/path-comparable
Open

[Stdlib] Add Comparable conformance to Path#6170
msaelices wants to merge 3 commits intomodular:mainfrom
msaelices:feat/path-comparable

Conversation

@msaelices
Copy link
Contributor

@msaelices msaelices commented Mar 14, 2026

Path already conforms to Equatable and Hashable, but was missing Comparable. This adds __lt__, __le__, __gt__, __ge__ with lexicographic ordering (delegating to the underlying String field), enabling Path values to be sorted and compared with <, >, <=, >=.


Assisted-by: AI

@msaelices msaelices requested a review from a team as a code owner March 14, 2026 21:42
Copilot AI review requested due to automatic review settings March 14, 2026 21:42
@github-actions github-actions bot added mojo-stdlib Tag for issues related to standard library waiting-on-review mojo-docs labels Mar 14, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands standard library comparability/hash/string-casing capabilities by adding ordering support to Path, pointer-identity Equatable/Hashable support to ArcPointer, and new capitalize()/title() APIs for String and StringSlice.

Changes:

  • Add Comparable conformance and comparison dunders (__lt__, __le__, __gt__, __ge__) to Path.
  • Add Equatable/Hashable conformance to ArcPointer with pointer-identity semantics and corresponding tests.
  • Add capitalize() and title() to StringSlice and forwarders on String, with new tests.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
mojo/stdlib/std/pathlib/path.mojo Adds Comparable conformance and ordering dunders to Path.
mojo/stdlib/test/pathlib/test_pathlib.mojo Adds tests for Path ordering and sorting.
mojo/stdlib/std/memory/arc_pointer.mojo Adds Equatable/Hashable conformances and implementations for pointer identity.
mojo/stdlib/test/memory/test_arc.mojo Adds tests for ArcPointer hashing and equality.
mojo/stdlib/std/collections/string/string_slice.mojo Implements StringSlice.capitalize() and StringSlice.title().
mojo/stdlib/std/collections/string/string.mojo Adds String.capitalize() / String.title() forwarding to StringSlice.
mojo/stdlib/test/collections/string/test_string_slice.mojo Adds tests for StringSlice.capitalize() / .title().
mojo/stdlib/test/collections/string/test_string.mojo Adds tests for String.capitalize() / .title().
mojo/docs/nightly-changelog.md Documents ArcPointer: Hashable (but not the other user-visible additions).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +61 to +64
- `ArcPointer` now conforms to the `Hashable` trait, enabling its use as a
`Dict` key or `Set` element. The hash is based on the allocation address,
consistent with pointer-identity semantics (`a is b` implies
`hash(a) == hash(b)`).
Comment on lines +2298 to +2308
def capitalize(self) -> String:
"""Returns a copy of the string with the first character uppercased and the rest lowercased.

Processes ASCII characters only. Non-ASCII characters are passed through unchanged.

Returns:
A new `String` with the first character uppercased and the remaining characters lowercased.
"""
if self.byte_length() == 0:
return String("")
var result = self.lower()
Comment on lines +2315 to +2341
def title(self) -> String:
"""Returns a title-cased version of the string.

Each word begins with an uppercase character, and the remaining characters are lowercase.
A word is defined as a sequence of consecutive alphabetic characters. Non-alphabetic
characters (spaces, digits, punctuation) act as word boundaries, consistent with Python's
`str.title()` behavior.

Processes ASCII characters only. Non-ASCII characters are passed through unchanged.

Returns:
A new `String` where each word's first character is uppercased and the rest are lowercased.
"""
var result = self.lower()
var prev_cased = False
var ptr = result.unsafe_ptr_mut()
var n = result.byte_length()
for i in range(n):
var b = ptr[i]
if b >= ord("a") and b <= ord("z"):
if not prev_cased:
ptr[i] = b - 32
prev_cased = True
elif b >= ord("A") and b <= ord("Z"):
prev_cased = True
else:
prev_cased = False
Comment on lines +1680 to +1705
def capitalize(self) -> String:
"""Returns a copy of the string with the first character uppercased and the rest lowercased.

Processes ASCII characters only. Non-ASCII characters are passed through unchanged.

Returns:
A new `String` with the first character uppercased and the remaining characters lowercased.
"""

return StringSlice(self).capitalize()

def title(self) -> String:
"""Returns a title-cased version of the string.

Each word begins with an uppercase character, and the remaining characters are lowercase.
A word is defined as a sequence of consecutive alphabetic characters. Non-alphabetic
characters (spaces, digits, punctuation) act as word boundaries, consistent with Python's
`str.title()` behavior.

Processes ASCII characters only. Non-ASCII characters are passed through unchanged.

Returns:
A new `String` where each word's first character is uppercased and the rest are lowercased.
"""

return StringSlice(self).title()
Comment on lines +127 to +136
# Two pointers to the same object hash identically.
assert_equal(hash(p), hash(q))

# A distinct allocation is a different pointer: its address differs, so its
# hash value differs (hash is the raw address, so no collision is possible
# for two simultaneously live allocations).
var r = ArcPointer(42)
assert_true(hash(p) != hash(r))


@msaelices msaelices force-pushed the feat/path-comparable branch from df3e149 to 4fda4aa Compare March 14, 2026 21:54
@msaelices msaelices changed the title [Stdlib] Add Comparable conformance to Path [Stdlib] Add Comparable conformance to Path Mar 14, 2026
@msaelices msaelices force-pushed the feat/path-comparable branch from 4fda4aa to 8feb56c Compare March 14, 2026 23:32
@msaelices msaelices force-pushed the feat/path-comparable branch from 8feb56c to 6f1bef4 Compare March 14, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mojo-docs mojo-stdlib Tag for issues related to standard library waiting-on-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants