Skip to content

Modern: validate regex_pattern type up front like max_length/separator - #8

Open
lomeliDev wants to merge 1 commit into
masterfrom
issue/5-modern-validate-regex-pattern-type-up-front-like-max
Open

lomeliDev wants to merge 1 commit into
masterfrom
issue/5-modern-validate-regex-pattern-type-up-front-like-max

Conversation

@lomeliDev

Copy link
Copy Markdown
Owner

Addresses issue #5 (#5); the issue stays open until a maintainer decides to merge and close it.

Root cause

The modern algorithm validates its caller-supplied arguments up front in
_modern_slugify (max_length, separator, text, replacement_stage,
backend), but the neighboring regex_pattern argument was skipped. It is
consumed much later by re.sub, so a bad value fails cryptically deep in the
pipeline — after entity decoding, transliteration and pre-replacements have
already run — with a message that names neither the argument nor the accepted
types:

>>> slugify('abc', algorithm='modern', regex_pattern=123)
TypeError: first argument must be string or compiled pattern

Fix (minimal)

Add the same guard the sibling arguments already have, right after the
separator check in slugify/slugify.py:

if regex_pattern is not None and not isinstance(regex_pattern, (str, re.Pattern)):
    raise TypeError(f"regex_pattern must be str, re.Pattern or None, not {type(regex_pattern).__name__}")

None and empty strings keep their documented behavior (empty string falls
back to the default pattern). Legacy (slugify/_legacy.py) is frozen and
untouched.

Lesson propagation

The issue is itself the propagation of the PR un33k#196 "validate up front" lesson
to the one neighboring argument that was missed. Scope is intentionally limited
to regex_pattern, as requested; other caller-supplied arguments that the
modern pipeline also consumes late (stopwords, replacements) are out of
scope for this issue and were left unchanged.

Files

  • slugify/slugify.py
  • tests/test_modern_unicode.py (new)

Evidencia

Vista roja (fix removed, test kept)

$ find . -name '__pycache__' -type d -exec rm -rf {} + ; find . -name '*.pyc' -delete
$ python3 -m pytest -p no:cacheprovider tests/test_modern_unicode.py -v
...
tests/test_modern_unicode.py::test_regex_pattern_type_is_validated_up_front FAILED
...
E       AssertionError: Regex pattern did not match.
E         Expected regex: 'regex_pattern'
E         Actual message: 'first argument must be string or compiled pattern'
1 failed, 1 passed

Vista verde (fix restored, test kept)

$ python3 -m pytest -p no:cacheprovider tests/test_modern_unicode.py -v
...
tests/test_modern_unicode.py::test_regex_pattern_type_is_validated_up_front PASSED
tests/test_modern_unicode.py::test_regex_pattern_accepts_str_and_compiled_pattern PASSED
2 passed

Suite completa (fix in place)

$ python3 -m pytest -p no:cacheprovider tests -q
20 failed, 114 passed, 8 skipped, 127 subtests passed

The 20 failures are pre-existing and unrelated to this change: every one is a
ModuleNotFoundError: No module named 'text_unidecode' (plus one CLI subprocess
failure that is the same missing dependency surfaced via python -m slugify).
text-unidecode is the mandatory base dependency but is not installed in this
sandbox; pip install is blocked by the externally-managed (PEP 668)
environment, and installing/downloading tooling is out of scope for this
worker. The 2 new tests in this PR both pass.

Quality gate (CI)

Reproduced against the taller-ci workflow (.github/workflows/taller-ci.yml),
which runs flake8, pycodestyle and pytest on a matrix of Python 3.11 and
3.12:

  • pytest: reproduced on the installed Python 3.11.2 (see above).
  • flake8 / pycodestyle: not reproduced — neither binary is installed in
    the sandbox and installing them is disallowed for this worker. The diff adds
    only simple, existing-style Python (no trailing whitespace, no new imports
    beyond the already-used re in slugify.py; the new test file imports only
    re, pytest and slugify). No risky modern syntax was introduced.
  • Python 3.12: not installed here; not reproduced (matches the 3.11 run for a
    syntax-neutral change).

Diff scope

The diff is confined to slugify/slugify.py and the new
tests/test_modern_unicode.py; no lockfiles, generated artifacts, or unrelated
files. (The issue suggested tests/test_modern_unicode.py, which did not yet
exist, so it is created here.)

🚀 Generated with Dojo ⛩️

@lomeliDev

Copy link
Copy Markdown
Owner Author

Revisión adversarial independiente — APROBABLE

Revisado por quien no escribió el código, en worktree propio (origin/pr/8), import resuelto al worktree (slugify/__init__.py del worktree, no el editable del clon principal), Python 3.11.2.

Puerta fiel al CI (taller-ci.yml). Reproduje los tres pasos exactos del workflow:

$ flake8 --ignore=E501,F403,F401,E241,E225,E128 --exclude=legacy_reference.py slugify setup.py tests tools   # exit 0
$ pycodestyle --ignore=E128,E261,E225,E501,W605 --exclude=legacy_reference.py slugify tests setup.py tools   # exit 0
$ python -m pytest -p no:cacheprovider tests -q        # 135 passed, 5 skipped, 136 subtests passed

(La base del fork era 133 passed; +2 por los tests nuevos, sin regresiones.) CI del fork verde en 3.11 y 3.12 (gh pr checks).

Vista roja/verde. Revertí slugify/slugify.py a origin/master dejando el test:

# SIN el guard:
FAILED test_regex_pattern_type_is_validated_up_front - AssertionError: Regex pattern did not match ('first argument must be string or compiled pattern')
test_regex_pattern_accepts_str_and_compiled_pattern PASSED
# CON el guard:
2 passed

Efectos secundarios / alcance: el guard es regex_pattern is not None and not isinstance(regex_pattern, (str, re.Pattern)). None y cadena vacía conservan su comportamiento documentado: '' pasa el guard y luego regex_pattern or (DEFAULT) recae en el patrón por defecto (cubierto por el 2º test). Sólo toca slugify/slugify.py y el test nuevo; _legacy.py intacto (la paridad diferencial del test_release pasa). Conforme a Archivos: de la issue #5.

Sin reparos.

— revisión adversarial automática, sesión Claude Code (independiente del autor).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant