A Python utility to format CPF (Brazilian Individual's Taxpayer ID).
Python Support
| Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ |
Features
- ✅ Flexible input: Accepts
stror a sequence ofstr; sequence elements are concatenated in order - ✅ Format agnostic: Strips non-digit characters before formatting
- ✅ Custom delimiters:
dot_keyanddash_keymay be empty, single-, or multi-character strings - ✅ Masking: Optional hiding of a digit range with a configurable replacement string (
hidden,hidden_key,hidden_start,hidden_end) - ✅ HTML & URL output: Optional
escape(HTML entities) andencode(URI component encoding, similar to JavaScriptencodeURIComponent) - ✅ Length errors without throwing: Invalid length after sanitization is handled via
on_fail(default returns an empty string) - ✅ Minimal dependencies: Only
lacus.utils - ✅ Error handling: Type errors for wrong API use; option validation via dedicated exception classes
Installation
$ pip install cpf-fmt
Import
from cpf_fmt import CpfFormatter, CpfFormatterOptions, cpf_fmt
Quick start
from cpf_fmt import CpfFormatter
formatter = CpfFormatter()
formatter.format('03603568195') # '036.035.681-95'
formatter.format('123.456.789-10') # '123.456.789-10'
formatter.format('12345678910') # '123.456.789-10'
Usage
The main entry points are the class CpfFormatter, the options class CpfFormatterOptions, and the helper cpf_fmt().
CpfFormatter
-
__init__: Optional default formatting options. The first parameter may beNone, a mapping of option keys, or aCpfFormatterOptionsinstance (that exact instance is stored; mutating it later affects subsequentformat()calls that do not pass per-call options). You may also pass option fields as keyword arguments (hidden,hidden_key,dot_key, …). Example:CpfFormatter(hidden=True, dash_key='_'). -
options: Property returning the instance’sCpfFormatterOptions(same object used internally). -
format(cpf_input, options=None, …): Formats a CPF value.Input is normalized by removing non-digit characters. If the sanitized length is not exactly 11, the
on_failcallback is invoked with the original input and aCpfFormatterInputLengthException; its return value is the result (nothing is thrown for length).If the input is not a
stror a sequence ofstr,CpfFormatterInputTypeErroris raised.Per-call options are merged over the instance defaults for that call only (instance defaults are unchanged). Pass a
CpfFormatterOptionsinstance or a mapping as the second argument, in addition to keyword arguments; when both are provided, theoptionsargument wins.
CpfFormatterOptions
Holds all formatter settings, with validation and merge support. Exposes properties: hidden, hidden_key, hidden_start, hidden_end, dot_key, dash_key, escape, encode, on_fail.
__init__(options=None, *extra_overrides, hidden=None, hidden_key=None, hidden_start=None, hidden_end=None, dot_key=None, dash_key=None, escape=None, encode=None, on_fail=None): Optional default options (plain mapping,CpfFormatterOptionsinstance, or keyword arguments), plus extra override objects merged in order (later overrides win).all: Returns a shallow copy of all current options.copy(): Returns a shallow copy of this options instance.set(options): Updates multiple fields at once; returnsself. Accepts a mapping or anotherCpfFormatterOptionsinstance.set_hidden_range(hidden_start, hidden_end): Validates indices in[0, 10](inclusive); ifhidden_start > hidden_end, values are swapped.Nonearguments fall back to defaults (DEFAULT_HIDDEN_START/DEFAULT_HIDDEN_END).
hidden_start / hidden_end: Indices refer to the 11-digit normalized CPF string (before inserting punctuation). The inclusive range is replaced internally by placeholders, then hidden_key is substituted (supports multi-character keys and empty string).
Key options (hidden_key, dot_key, dash_key): Must be strings and must not contain any character in CpfFormatterOptions.DISALLOWED_KEY_CHARACTERS (reserved for internal formatting).
Functional helper
cpf_fmt() builds a new CpfFormatter from the same constructor parameters and calls format(cpf_input) once. Use keyword arguments, a mapping, or a CpfFormatterOptions instance for options:
from cpf_fmt import cpf_fmt
cpf = '03603568195'
cpf_fmt(cpf) # '036.035.681-95'
cpf_fmt(cpf, hidden=True) # masked with defaults
cpf_fmt( # '036035681_95'
cpf,
dot_key='',
dash_key='_',
)
cpf_fmt(cpf, { # mapping form
'hidden': True,
'hidden_key': '#',
})
Object-oriented examples
from cpf_fmt import CpfFormatter
formatter = CpfFormatter()
cpf = '12345678910'
formatter.format(cpf) # '123.456.789-10'
formatter.format( # '123.###.###-##'
cpf,
hidden=True,
hidden_key='#',
hidden_start=3,
hidden_end=10,
)
Default options on the instance; per-call overrides:
formatter = CpfFormatter(hidden=True)
formatter.format(cpf) # uses instance masking
formatter.format(cpf, hidden=False) # this call only: unmasked
formatter.format(cpf) # back to instance defaults
Sequence input:
formatter.format([ # '123.456.789-10'
'123',
'456',
'789',
'10',
])
Input formats
String: Raw digits, or already formatted CPF (e.g. 123.456.789-10, 123 456 789 10). Non-digit characters are removed; leading zeros are preserved.
Sequence of strings: Each element must be a str; values are concatenated (e.g. per digit, grouped segments, or mixed with punctuation — all non-digits are stripped during normalization). Non-string elements are not allowed.
Formatting options
| Parameter | Type | Default | Description |
|---|---|---|---|
hidden |
bool | None |
False |
When True, replaces the inclusive index range [hidden_start, hidden_end] on the normalized 11-digit string before punctuation is applied |
hidden_key |
str | None |
'*' |
Replacement for each hidden position (may be multi-character or empty); must not use disallowed key characters |
hidden_start |
int | None |
3 |
Start index 0–10 (inclusive) |
hidden_end |
int | None |
10 |
End index 0–10 (inclusive); if hidden_start > hidden_end, they are swapped |
dot_key |
str | None |
'.' |
Separator after the 3rd and 6th digits |
dash_key |
str | None |
'-' |
Separator after the 9th digit |
escape |
bool | None |
False |
When True, HTML-escapes the final string |
encode |
bool | None |
False |
When True, URL-encodes the final string (similar to encodeURIComponent) |
on_fail |
Callable | None |
see below | (value, exception) -> str — used when sanitized length ≠ 11 |
Default on_fail returns an empty string. The exception passed for length failures is CpfFormatterInputLengthException (actual_input, evaluated_input, expected_length).
Example with all options:
from cpf_fmt import cpf_fmt
cpf = '12345678910'
cpf_fmt(
cpf,
hidden=True,
hidden_key='#',
hidden_start=3,
hidden_end=9,
dot_key=' ',
dash_key='_-_',
escape=True,
encode=True,
on_fail=lambda value, exception: str(value),
)
Errors & exceptions
- Wrong input type (not
stror a sequence ofstr):CpfFormatterInputTypeError— extendsCpfFormatterTypeError(extends built-inTypeError). - Invalid option types or values when constructing or merging options:
CpfFormatterOptionsTypeError,CpfFormatterOptionsHiddenRangeInvalidException,CpfFormatterOptionsForbiddenKeyCharacterException— extendCpfFormatterTypeErrororCpfFormatterExceptionas appropriate.
Length mismatch does not throw from format(); handle it inside on_fail.
from cpf_fmt import (
CpfFormatter,
CpfFormatterInputLengthException,
CpfFormatterInputTypeError,
)
try:
CpfFormatter().format(12345)
except CpfFormatterInputTypeError as e:
e # handle type error
CpfFormatter().format(
'short',
on_fail=lambda value, exception: 'invalid',
) # 'invalid'
API
Exports
All public symbols are available from the cpf_fmt package:
cpf_fmt:(cpf_input: CpfInput, options=None, **kwargs) -> str— convenience helper.CpfFormatter: Class to format CPF with optional default options; acceptsCpfInputinformat().CpfFormatterOptions: Class holding options; supports merge via constructor,set(), and keyword arguments.CPF_LENGTH:11(constant).CpfInput: Type alias —str | Sequence[str].- Exceptions:
CpfFormatterTypeError,CpfFormatterInputTypeError,CpfFormatterOptionsTypeError,CpfFormatterException,CpfFormatterInputLengthException,CpfFormatterOptionsHiddenRangeInvalidException,CpfFormatterOptionsForbiddenKeyCharacterException.
Other available resources
CpfFormatterOptions.CPF_LENGTH:11.CpfFormatterOptions.DISALLOWED_KEY_CHARACTERS: Characters forbidden inhidden_key,dot_key,dash_key.CpfFormatterOptions.DEFAULT_*: Default values for each option.
Contribution & Support
We welcome contributions! Please see our Contributing Guidelines for details. If you find this project helpful, please consider:
- ⭐ Starring the repository
- 🤝 Contributing to the codebase
- 💡 Suggesting new features
- 🐛 Reporting bugs
License
This project is licensed under the MIT License — see the LICENSE file for details.
Changelog
See CHANGELOG for a list of changes and version history.
Made with ❤️ by Lacus Solutions
Metadata
Release files for cpf-fmt 2.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cpf_fmt-2.0.1.tar.gz | 19.3 kB | Without provenance | Details for cpf_fmt-2.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cpf_fmt-2.0.1-py3-none-any.whl | Python 3 | none | any | Details for cpf_fmt-2.0.1-py3-none-any.whl |
Total release size: 37.3 kB
Release files / cpf_fmt-2.0.1.tar.gz
| Download URL | cpf_fmt-2.0.1.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
436b2b280b296a9bebc669dd7a6ae699817fa80812cdddc7dab93eda49ffbc59
|
|
BLAKE2b-256 checksum How to use checksums |
a852c6dd01482c74e7dd4e8430d5b1a7e6c54008b81289038ae5076fff9a36d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / cpf_fmt-2.0.1-py3-none-any.whl
| Download URL | cpf_fmt-2.0.1-py3-none-any.whl |
|---|---|
| Size | 18.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19d1ef012a917474b4db39a47de486130227f60d1a4bb565cdae62073555db8f
|
|
BLAKE2b-256 checksum How to use checksums |
07877bf3f7fa09f5461dd028b862cc5c710a248437eb367fa61a914cd091cdf9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Security for cpf-fmt 2.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.