mrkeyoor.com_
Sun 20 Sept 19:54 UTC
PyPIUtilsupdated 20 Sept 2026

inflection review

inflection 0.5.1 ports the naming rules from Rails into a compact Python module. It converts identifiers among CamelCase, snake_case, dashed, title, parameter, and human-label forms, then handles common English singulars and plurals with ordered regex tables plus irregular and uncountable lists. This is convention code, not a language parser. Version 0.5.1 reorganized the distribution so the included `py.typed` marker is discovered by mypy. Our Python 3.12 check found no dependencies and a 0.05-second import.

Verdict

inflection 0.5.1 installed as 1 MB with no dependencies and imported in 0.05 seconds in our sandbox. Use it for tested Rails-compatible identifiers; avoid it for open-ended English words or international slug generation.

We installed it

Lab card: what happened when we installed inflectionScreenshot of inflection documentation
Install✓ · 0.2s1 package on disk · 1 MB
Importimport inflection in 0.05s · pure Python · py.typed · requires Python >=3.5
Known vulns0(pip-audit)

Answers from our run

Does inflection install cleanly?

Yes. In a fresh container with an empty cache, pip install inflection finished in 0.2s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does inflection need to run?

Python >=3.5, and nothing compiled: it is pure Python. In our run import inflection succeeded in 0.05s, and the package ships py.typed for type checkers.

inflection or inflect: which should you use?

inflect: Use it for a deeper English vocabulary, number words, articles, and more irregular nouns. inflection 0.5.1 installed as 1 MB with no dependencies and imported in 0.05 seconds in our sandbox.

When should you not use inflection?

The job is English morphology rather than application naming. Its Rails tables omit foot, tooth, goose, and criterion, while cow becomes kine.

API stability5/5Version 0.5.1 exposes a small set of direct functions: `camelize`, `underscore`, `pluralize`, `singularize`, `tableize`, `humanize`, and `parameterize` among them. Its only release change was packaging the typed marker correctly, not replacing these calls. With no release since August 2020, existing results are very unlikely to shift, although questionable rules are just as unlikely to receive a fix.
Docs3/5Read the Docs lists every public function with concrete before-and-after strings, including lower camel mode, acronym loss, separators, ordinals, and table naming. It does not publish the complete irregular-word set, explain regex precedence, define a safe extension contract, or warn prominently that ASCII transliteration can erase a whole script. Production use still calls for source reading and fixtures built from real names.
Maintenance2/5PyPI dates 0.5.1 to August 22, 2020. The unarchived GitHub repository has 525 stars, 32 open issues and pull requests, and a last push on August 13, 2023. Our Python 3.12 run proves the dependency-free code still executes today, but it does not supply a current release path for language-rule corrections, packaging requests, or future interpreter breakage.
Ecosystem4/5The stored registry count is 11,263,201 downloads per week. Rails-compatible naming is useful in ORMs, serializers, and generators that exchange conventions across Ruby and Python, while 0 dependencies make transitive adoption cheap. The surrounding use is broad but the feature domain is narrow: nested payload keys, full English grammar, and multilingual slugs need different libraries.

Use it if

  • Python models must reproduce Rails table or resource names without maintaining another inflection table.
  • A generator needs dependency-free conversions among class names, underscored identifiers, dashed names, and labels.
  • The relevant nouns come from a controlled domain list and every output can be pinned in tests.
  • A typed pure-Python helper must continue running on interpreters as old as Python 3.5.
Skip it if

Setup reality

We installed inflection 0.5.1 without a cache on Python 3.12 in 0.2 seconds. Exactly 1 package and 1 MB remained, with 0 direct dependencies and 0 known pip-audit vulnerabilities. It is pure Python, MIT-licensed, and declares Python >=3.5. The package includes py.typed; import inflection completed in 0.05 seconds.

There is no service, credential, native compiler, or config file. The real setup is a fixture table of your names and expected results. tableize() first underscores and then pluralizes, so an odd noun rule can become a permanent database name. Guard empty input before camelize(value, False) because that branch reads character zero and raises IndexError for ''.

Plural and singular patterns are mutable module-level lists evaluated in order. A custom regex belongs ahead of broader built-ins, but inserting it changes behavior for every importer in that interpreter. For a few domain terms, keep an application dictionary beside the naming tests. That avoids a library silently changing another package's table calculation.

transliterate() uses NFKD normalization followed by ASCII encoding with errors ignored. Accents on many Latin letters survive as plain characters; scripts without ASCII decompositions may vanish. parameterize() inherits that loss and can return an empty slug. Use a cross-script transliterator for public names, and always reject an empty generated identifier. There is no cache beyond those shared rule tables.

Patterns

Translate between identifier conventions convert-case

import inflection

inflection.underscore('HTTPResponse')      # 'http_response'
inflection.camelize('device_type')         # 'DeviceType'
inflection.camelize('device_type', False)  # 'deviceType'
inflection.dasherize('device_type')        # 'device-type'

`underscore()` discards acronym boundaries, so a later camel conversion cannot reconstruct the original `HTTPResponse` spelling.

Handle an empty lower-camel input guard-empty-camelize

import inflection

def lower_camel(value: str) -> str:
    if value == '':
        return value
    return inflection.camelize(value, False)

Version 0.5.1 indexes character zero in lower-camel mode; passing an empty string raises `IndexError`.

Walk nested payload keys explicitly map-json-keys

import inflection

def camel_keys(value):
    if isinstance(value, dict):
        return {inflection.camelize(k, False): camel_keys(v) for k, v in value.items()}
    if isinstance(value, list):
        return [camel_keys(v) for v in value]
    return value

inflection only accepts one string. If this recursion is the whole feature, pyhumps already covers dictionaries and lists.

Derive a Rails-compatible table name derive-table-name

import inflection

class RawScaledScorer:
    pass

table = inflection.tableize(RawScaledScorer.__name__)
assert table == 'raw_scaled_scorers'

`tableize()` composes case conversion with pluralization. Assert the final database identifier before generating a migration.

Run known nouns through the Rails tables pluralize-noun

import inflection

inflection.pluralize('analysis')   # 'analyses'
inflection.pluralize('child')      # 'children'
inflection.pluralize('sheep')      # 'sheep'
inflection.singularize('indices')  # 'index'

These examples are present in the rule vocabulary. Add fixtures for every domain noun instead of extrapolating to arbitrary English.

Prefer a local irregular-word map override-irregulars

import inflection

PLURALS = {
    'foot': 'feet',
    'goose': 'geese',
    'criterion': 'criteria',
}

def plural(word: str) -> str:
    return PLURALS.get(word.lower(), inflection.pluralize(word))

An application dictionary is isolated and reviewable; changing inflection's globals affects every package in the interpreter.

Patch the global regex order when unavoidable register-global-rule

import inflection

inflection.PLURALS.insert(0, (r'(?i)(f)oot$', r'\1eet'))
inflection.SINGULARS.insert(0, (r'(?i)(f)eet$', r'\1oot'))

Earlier regexes win. This mutates undocumented shared lists, so insert before broad rules and confine the change to application startup.

Generate a label from an internal field humanize-field

import inflection

inflection.humanize('employee_salary')  # 'Employee salary'
inflection.humanize('author_id')        # 'Author'
inflection.titleize('order_status')      # 'Order Status'

`humanize()` strips a terminal `_id`. Use an explicit label when those characters are meaningful rather than a database suffix.

Parameterize text that already transliterates safely make-url-slug

import inflection

inflection.parameterize('Donald E. Knuth')      # 'donald-e-knuth'
inflection.parameterize('Hello, World!', '_')   # 'hello_world'

Non-Latin input may collapse to an empty result during ASCII conversion. Reject empty output before using it as a URL key.

Reduce compatible Latin characters to ASCII transliterate-latin

import inflection

plain = inflection.transliterate('cafe')
slug = inflection.parameterize(plain)

Characters without an ASCII decomposition are discarded. Use Unidecode or another transliterator for readable cross-script approximations.

Append an English ordinal suffix format-ordinal

import inflection

inflection.ordinal(22)       # 'nd'
inflection.ordinalize(22)    # '22nd'
inflection.ordinalize(-3)    # '-3rd'

`ordinal()` returns the suffix alone; `ordinalize()` includes the number. Version 0.5.1 has no locale parameter.

Pin model-to-table names before migration test-schema-words

import pytest
import inflection

@pytest.mark.parametrize(('model', 'table'), [
    ('Person', 'people'),
    ('Category', 'categories'),
    ('Analysis', 'analyses'),
])
def test_table_name(model, table):
    assert inflection.tableize(model) == table

A fixture exposes a domain noun that Rails rules mishandle before its result is stored as a schema identifier.

Alternatives

PackageRegistryPick it when
inflectPyPIUse it for a deeper English vocabulary, number words, articles, and more irregular nouns.
pyhumpsPyPIUse it when case changes must walk nested lists and dictionaries automatically.
python-slugifyPyPIUse it for public slugs that need Unicode choices, replacements, length controls, and stop words.
UnidecodePyPIUse it when non-Latin scripts should become approximate readable ASCII rather than disappear.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.