fix: present_participle('be') returns 'bing' instead of 'being' - #252
fix: present_participle('be') returns 'bing' instead of 'being'#252gaoflow wants to merge 2 commits into
Conversation
The PRESENT_PARTICIPLE_REPLACEMENTS rule `([^e])e$` drops the trailing 'e' from any word ending in a non-e consonant + e. This incorrectly strips 'be' down to 'b', yielding 'bing'. Add an explicit guard for '^be$' ahead of that rule so 'be' passes through intact and produces 'being'.
eeshsaxena
left a comment
There was a problem hiding this comment.
Confirmed the bug on main:
>>> p.present_participle("be")
'bing'The reason is that "be" reaches (re.compile(r"([^e])e$"), r"\g<1>"), which strips the trailing e after a non-e consonant (the rule that correctly turns hate into hating), leaving b + ing. Inserting ^(be)$ as an identity replacement above it short-circuits the loop before that rule is reached, which is the same trick the existing ^(hoe)$ entry uses. Placement is right: it has to sit above ([^e])e$ to have any effect.
I applied the rule to a local copy and diffed the output over the existing test words plus a set of neighbours that could plausibly be caught by the new pattern:
word before after
be bing being <-- changed
are being being
were being being
had having having
hoe hoeing hoeing
bee beeing beeing
see seeing seeing
hate hating hating
spies spying spying
skis skiing skiing
free freeing freeing
die dying dying
use using using
make making making
be is the only word whose output changes, so the fix is properly surgical - the anchored ^(be)$ cannot catch bee, been or anything else.
One thing worth being aware of (not a blocker): present_participle's docstring says "word is the 3rd person singular verb", and the documented input already works, because plural_verb("is", 2) returns "are" and the existing ^(are|were)$ rule maps that to be:
>>> p.present_participle("is")
'being'So "be" is a bare infinitive rather than the documented 3rd-person-singular form. That said, the function is already tolerant of infinitives everywhere else (hoe, see, make all work), bing is not a correct participle for any input, and ^(hoe)$ exists precisely to patch one of these. So I think accepting be is consistent with how the table already behaves rather than a scope expansion.
Two small suggestions:
- Consider folding it into the neighbouring rule as
^(hoe|be)$instead of a separate entry - same behaviour, one fewer regex to walk, and it groups the "identity, do not strip thee" cases together. Purely cosmetic. - The added test could also pin the documented path, so a future reordering of the table cannot silently break it:
assert p.present_participle("be") == "being"
assert p.present_participle("is") == "being" # documented 3rd-person-singular inputNice, well-scoped fix otherwise. Deferring to @jaraco.
…nput
Fold ^(be)$ into the neighbouring ^(hoe)$ entry (same replacement, one
fewer regex to walk) and add a present_participle("is") assertion so the
documented 3rd-person-singular path is pinned against future reordering.
|
Thanks for the thorough check. Applied both in d6665df:
Confirmed no output changes across your neighbour list ( |
Summary
present_participle('be')produces'bing'instead of'being'.The root cause is the catch-all rule
([^e])e$inPRESENT_PARTICIPLE_REPLACEMENTS, which drops the trailingefromany word ending in e. For a two-letter word like
bethat leaves onlyb, then+ ing = bing.The fix adds an explicit guard
^(be)$immediately before that rule(consistent with the existing guards for
are,were,had,hoe)so
bepasses through intact and producesbeing.Test plan
assert p.present_participle("be") == "being"added totest_prespart