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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cpf_fmt-2.0.1.tar.gz.
File metadata
- Download URL: cpf_fmt-2.0.1.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
436b2b280b296a9bebc669dd7a6ae699817fa80812cdddc7dab93eda49ffbc59
|
|
| MD5 |
03bcbd31424d982c4af507c6533827de
|
|
| BLAKE2b-256 |
a852c6dd01482c74e7dd4e8430d5b1a7e6c54008b81289038ae5076fff9a36d6
|
File details
Details for the file cpf_fmt-2.0.1-py3-none-any.whl.
File metadata
- Download URL: cpf_fmt-2.0.1-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19d1ef012a917474b4db39a47de486130227f60d1a4bb565cdae62073555db8f
|
|
| MD5 |
a770644575dccb01ae309784c2a33777
|
|
| BLAKE2b-256 |
07877bf3f7fa09f5461dd028b862cc5c710a248437eb367fa61a914cd091cdf9
|