mrkeyoor.com_
Sat 08 Aug 20:59 UTC
PyPIUtilsupdated 08 Aug 2026

binaryornot

BinaryOrNot is a zero-dependency Python library and command-line program that guesses whether a file or byte chunk is binary or text. Version 0.6 reads at most the first 512 bytes, checks known file extensions and magic signatures, then applies a trained decision tree to byte ratios, entropy, printable runs, byte-order marks, and validity under several Unicode and CJK encodings. The answer is a Boolean classification, not an encoding name, MIME type, or guarantee that later bytes are text-safe.

Verdict

BinaryOrNot is a good lightweight routing heuristic and much smarter than searching for a null byte. Do not use its Boolean as proof that arbitrary content is safe, correctly encoded, or a particular file type.

API stability4/5The main import, binaryornot.check.is_binary, remains a single Boolean-returning function, and is_binary_string remains available for bytes. Version 0.6 adds the keyword-only check_extensions control and raises the Python floor to 3.10, which is meaningful for older applications but keeps ordinary current-Python call sites clear and small.
Docs4/5The README and documentation explain the 512-byte limit, all 24 decision-tree feature families, covered Unicode and CJK encodings, four known encoding gaps, and 49 tracked binary formats. Examples cover files, bytes, and the CLI. The site does not provide a confidence score, false-positive benchmark, threat model, or extensive operational guidance for ambiguous input.
Maintenance4/5Version 0.6.0 was uploaded in March 2026 and the repository was pushed in May 2026, replacing the older simplistic behavior with documented data-driven coverage and tests. The GitHub snapshot has 17 open issues and pull requests against a small 149-star project, so maintenance is active but concentrated and should not be assumed to have the staffing of a major parser.
Ecosystem3/5The package has a stable role in Python project-template and file-processing dependency trees, has no runtime dependencies, accepts pathlib paths, and provides a console command. Its intentionally tiny API does not integrate with MIME databases, upload frameworks, encoding detectors, streams, or async files directly, so ecosystem value is mostly composability rather than plugins.

Use it if

  • You need a fast first-pass filter before opening unknown files as text
  • You process mixed UTF, legacy CJK, archive, image, font, executable, and document files where a null-byte check is too crude
  • You want both a one-function Python API and a tiny CLI with no runtime dependencies
  • You can tolerate heuristic classification and have a separate policy for ambiguous or high-risk inputs
Skip it if

Setup reality

pip install binaryornot installs version 0.6 with no declared runtime dependencies, but it now requires Python 3.10 or newer. The common API accepts a string path, bytes path, or pathlib.Path and opens the target in binary mode. Missing files and permission errors are normal filesystem exceptions; the library does not turn them into False. By default it first checks the filename extension against a packaged list of known binary extensions, then reads only the first 512 bytes if the extension did not decide the result. Set check_extensions=False when a misleading user-controlled suffix should not outweigh content, or call is_binary_string when you already hold bytes. Empty bytes are classified as text. The decision tree considers 24 features and known signatures, but it is still a classifier, not a parser. The docs list four known encoding gaps, including ISO-2022-KR and three EBCDIC code pages, and only the file prefix is examined. A file may also be both meaningfully text and structurally binary, such as a container with a readable preamble. Treat the Boolean as routing advice: attempt decoding with explicit error handling, enforce size and path controls separately, and let a real format parser validate any untrusted upload. The CLI accepts one filename and prints True or False; it has no recursive directory mode, stdin byte mode, JSON output, or confidence score, so batch workflows need a small Python wrapper.

Patterns

Classify a file pathclassify-file

from binaryornot.check import is_binary

if is_binary("uploads/report.csv"):
    print("binary")
else:
    print("text")

The result is a heuristic based on extension and at most the first 512 bytes.

Classify pathlib entriesuse-pathlib-path

from pathlib import Path
from binaryornot.check import is_binary

text_files = [path for path in Path("docs").rglob("*") if path.is_file() and not is_binary(path)]

Handle permission and disappearing-file errors if the directory can change during traversal.

Classify content despite its suffixignore-file-extension

from binaryornot.check import is_binary

content_says_binary = is_binary("suspicious.txt", check_extensions=False)

Disabling extension checks is useful for untrusted names, but the content decision still sees only the first chunk.

Classify bytes already in memoryclassify-byte-chunk

from binaryornot.helpers import is_binary_string

with open("mystery.dat", "rb") as stream:
    chunk = stream.read(512)

print(is_binary_string(chunk))

Pass bytes, not str. Empty bytes return False and are treated as text-like.

Use classification before explicit decodingroute-text-decoding

from pathlib import Path
from binaryornot.check import is_binary

path = Path("incoming/message.txt")
if is_binary(path, check_extensions=False):
    raise ValueError("binary input is not accepted")
text = path.read_text(encoding="utf-8", errors="strict")

A False result does not identify UTF-8, so decoding still needs a chosen encoding and error policy.

Separate a batch for later processingfilter-upload-batch

from binaryornot.check import is_binary

text_paths, binary_paths = [], []
for path in uploaded_paths:
    target = binary_paths if is_binary(path, check_extensions=False) else text_paths
    target.append(path)

Use a real parser and independent upload limits after routing; classification is not validation.

Handle unreadable paths explicitlyhandle-file-errors

from binaryornot.check import is_binary

try:
    binary = is_binary(path)
except (FileNotFoundError, PermissionError, IsADirectoryError) as error:
    logger.warning("cannot inspect %s: %s", path, error)
    binary = None

The library lets filesystem exceptions propagate instead of converting an unreadable target into a guess.

Check one file from the shelluse-command-line

binaryornot README.md
# False

binaryornot image.png
# True

The CLI handles one filename per invocation and prints a Python-style Boolean, not JSON or a confidence score.

Alternatives

PackageRegistryPick it when
filetypePyPIYou need a pure-Python guess of the specific binary format from magic bytes
puremagicPyPIYou want pure-Python magic-number matching with extension and MIME information
python-magicPyPIYou can install the system libmagic library and need broad MIME or descriptive type detection