PyReprism is a Python framework that helps researchers and developers the task of source code preprocessing. With PyReprism, you can easily match, extract, count, and remove comments, whitespaces, operators, numbers and other language specific constructs from over 150 programming languages and file extensions.
pip install PyReprismThe simplest entry point is the top-level API. Pass lang as a language name
("python"), a file extension (".py"), or a language class.
import PyReprism as pr
source = """
# single line comment
x = 5 + 6
print(x) # inline comment
"""
pr.remove_comments(source, lang="python") # -> code with comments stripped
pr.extract_comments(source, lang="python") # -> ['# single line comment', '# inline comment']
pr.count_comments(source, lang="python") # -> 2Every construct supports the same match / extract / count / remove verbs:
code = 'total = price * 42 + tax # compute'
pr.extract_numbers(code, lang="python") # -> ['42']
pr.extract_keywords(code, lang="python") # -> []
pr.extract_identifiers(code, lang="python") # -> ['total', 'price', 'tax', 'compute']
pr.remove_numbers(code, lang="python") # -> 'total = price * + tax # compute'
pr.extract_strings('s = "hi"', lang="python") # -> ['"hi"']match_* returns positioned Tokens (type, value, start, end, line):
for tok in pr.match_comments(source, lang="python"):
print(tok.line, tok.value)tokenize() returns a lossless, typed token stream (comment/string/number/
keyword/identifier/operator/whitespace/other):
for tok in pr.tokenize("x = 5 + y // c", lang="clike"):
print(tok.type, repr(tok.value))Chain removal steps in one call:
pr.preprocess(source, lang="java",
steps=["comments", "strings", "whitespace"])Valid steps: comments, strings, numbers, operators, keywords, whitespace.
s = pr.stats(source, lang="python")
s.code_lines, s.comment_lines, s.blank_lines
s.comment_to_code_ratio, s.comment_density
s.as_dict() # includes per-token-type counts, ready for JSON / dataframesCanonicalize code so that only its structure remains — rename identifiers to
VAR1, VAR2, …, mask string/number literals, and drop comments:
pr.normalize("total = price * 42 # cost", lang="python")
# -> 'VAR1 = VAR2 * 0'Every part is toggleable (rename_identifiers, mask_numbers, mask_strings,
drop_comments, collapse_whitespace). To strip comments while keeping line
numbers stable (useful for tools that map back to source):
pr.blank_comments(source, lang="python") # comment content removed, newlines keptBy default PyReprism uses its own zero-dependency regex engine (fast, no installs).
For higher accuracy — e.g. correctly ignoring a # inside a string — pass
engine="pygments" (install the optional extra with pip install pyreprism[accurate]):
src = 'url = "http://x#frag" # real comment'
pr.remove_comments(src, lang="python") # regex (default)
pr.remove_comments(src, lang="python", engine="pygments") # keeps the URL, drops the commentengine accepts "regex" (default), "pygments", or "auto" (use pygments if
installed, else regex). It works on every operation — remove_*, extract_*,
count_*, tokenize, normalize, stats, preprocess — and on the CLI via
--engine.
Analyze or transform an entire source tree (junk folders like .git,
node_modules, venv are skipped automatically):
from PyReprism import batch
report = batch.analyze("myproject/") # walk the tree, compute metrics
report.totals() # aggregate line/token counts
report.by_language() # per-language breakdown
report.to_json(); report.to_csv() # export for dataframes / notebooks
# Bulk-transform into a mirrored output directory:
batch.transform("myproject/", lambda text, lang: lang.remove_comments(text),
output="stripped/")Parse a unified (git) diff and analyze the changed code per file, language-aware:
from PyReprism import diffs
d = diffs.parse(diff_text) # git diff / .diff / .patch text
report = diffs.diff_stats(d) # churn split into code vs comment vs blank
report.totals(); report.to_csv()
diffs.cosmetic_files(d) # files whose change is comment/whitespace-only
f = d.files[0]
f.language # detected from the file path
f.added_text(); f.removed_text() # reconstructed changed code
f.normalize("added") # canonicalize the added code for ML
f.extract_comments("added")For accuracy where a comment/string spans a hunk boundary, set
f.new_source / f.old_source to the full file contents (e.g. from git show)
and the changed lines are classified against the whole file. On the CLI:
git diff | pyreprism diff --per-file # churn report
git diff | pyreprism diff --json
git diff | pyreprism diff --cosmetic # list comment/whitespace-only changescls = pr.detect_language(filename="src/main.go") # -> Go language classpr.remove_whitespaces("x = 5 + 6\n\n\nprint(x)") # -> 'x=5+6\nprint(x)'You can also import a language class directly if you prefer:
from PyReprism.languages import Python
Python.remove_comments(source)Installing PyReprism also provides a pyreprism command (works on stdin/stdout,
files, and globs; the language is auto-detected from a file's extension):
pyreprism remove comments file.py
cat file.go | pyreprism remove comments --lang go
pyreprism extract comments "src/**/*.py" --json
pyreprism count comments file.py --lang python
pyreprism preprocess --steps comments,strings,whitespace file.java
pyreprism tokenize --json file.py
pyreprism stats --json file.py # line/token metrics
pyreprism normalize file.py # canonicalize for ML
pyreprism remove comments file.py --in-place # rewrite in place
pyreprism scan myproject/ --csv # aggregate metrics over a tree
pyreprism remove comments src/ --output out/ # bulk-transform a directory
pyreprism languages # list supported languagesEquivalently: python -m PyReprism ....
It can also be wired into pre-commit via the bundled
.pre-commit-hooks.yaml (pyreprism-strip-comments, pyreprism-normalize-whitespace).
These hooks rewrite files, so scope them with files:/exclude:.
Read the docs for more usage examples.
NB: The beta versions of PyReprism is still unstable, but we are working 24/7 to ensure the tool is usable.
We invite you to help us build this tool and make it more extensive. Contribution is open to OSS community.
$ git clone https://github.com/unlv-evol/PyReprism.git
$ cd PyReprism(Optional) It is suggested to make use of virtualenv. Therefore, before installing the requirements run:
$ python3 -m venv venv
$ source venv/bin/activateThen, install the package in editable mode with its development tooling:
$ pip install -e ".[dev]"For more information on how to contribute, read our contributing guidelines.
If you experience any issue, feel free to report it.