Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ BINDIR = $(PWD)/.state/env/bin
$(BINDIR)/python -m pip install -r requirements/dev.txt

build: .state/env/pyvenv.cfg
$(BINDIR)/python _internal/generator.py
$(BINDIR)/python -m _internal.generator

test: .state/env/pyvenv.cfg
$(BINDIR)/pytest
$(eval TMPDIR := $(shell mktemp -d))
$(BINDIR)/python _internal/generator.py --output $(TMPDIR)/test.py
$(BINDIR)/python -m _internal.generator --output $(TMPDIR)/test.py
diff trove_classifiers/__init__.py $(TMPDIR)/test.py

lint: .state/env/pyvenv.cfg
Expand Down
2 changes: 1 addition & 1 deletion _internal/classifiers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from models import ClassifierRoot, ClassifierNode
from .models import ClassifierRoot, ClassifierNode

classifiers = ClassifierRoot(
children=[
Expand Down
2 changes: 2 additions & 0 deletions _internal/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class InvalidClassifier(Exception):
pass
2 changes: 1 addition & 1 deletion _internal/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from jinja2 import Template

from classifiers import classifiers
from .classifiers import classifiers

parser = argparse.ArgumentParser()
parser.add_argument(
Expand Down
16 changes: 15 additions & 1 deletion _internal/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from .exceptions import InvalidClassifier


class ClassifierRoot:
def __init__(self, children):
self.children = children
Expand All @@ -23,10 +26,21 @@ def __init__(
skip=False,
):
if deprecated_by and not deprecated:
raise Exception(
raise InvalidClassifier(
"Using deprecated_by, but not marking the classifier as deprecated"
)

if short_name.lower().startswith("private"):
raise InvalidClassifier("Classifiers starting with 'Private' are invalid")

if short_name.strip().rstrip() != short_name:
raise InvalidClassifier(
"Classifiers starting or ending with whitespace are invalid"
)

if ":" in short_name:
raise InvalidClassifier("Classifiers containing ':' are invalid")

self.short_name = short_name
self.prefix_list = []
self.deprecated = deprecated
Expand Down
2 changes: 0 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

from setuptools import setup, find_packages

from trove_classifiers import classifiers

here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
Expand Down
52 changes: 44 additions & 8 deletions tests/test_classifiers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from _internal.models import ClassifierRoot, ClassifierNode
from _internal.exceptions import InvalidClassifier


def test_nested_prefixes():
Expand All @@ -13,10 +14,10 @@ def test_nested_prefixes():
]
)

assert root.generate() == [
ClassifierNode("Foo"),
ClassifierNode("Foo :: Bar"),
ClassifierNode("Foo :: Bar :: Baz"),
assert [node.full_name for node in root.generate()] == [
"Foo",
"Foo :: Bar",
"Foo :: Bar :: Baz",
]


Expand All @@ -31,12 +32,47 @@ def test_skip():
]
)

assert root.generate() == [
ClassifierNode("Foo :: Bar"),
ClassifierNode("Foo :: Bar :: Baz"),
assert [node.full_name for node in root.generate()] == [
"Foo :: Bar",
"Foo :: Bar :: Baz",
]


def test_bad_deprecation_failure():
with pytest.raises(Exception):
with pytest.raises(InvalidClassifier) as excinfo:
ClassifierNode("blah", deprecated_by=["spam"])

assert excinfo.value.args == (
"Using deprecated_by, but not marking the classifier as deprecated",
)


@pytest.mark.parametrize(
"parent, child",
[("Private", "Foo"), ("private", "Foo"), ("Foo", "Private"), ("Foo", "private"),],
)
def test_private_classifier_failure(parent, child):
with pytest.raises(InvalidClassifier) as excinfo:
ClassifierNode(
parent, children=[ClassifierNode(child)],
)

assert excinfo.value.args == ("Classifiers starting with 'Private' are invalid",)


@pytest.mark.parametrize("classifier", [" Foo", "Foo "])
def test_whitespace_classifier_failure(classifier):
with pytest.raises(InvalidClassifier) as excinfo:
ClassifierNode(classifier)

assert excinfo.value.args == (
"Classifiers starting or ending with whitespace are invalid",
)


@pytest.mark.parametrize("classifier", ["Foo:", "Foo :: Bar"])
def test_colon_classifier_failure(classifier):
with pytest.raises(InvalidClassifier) as excinfo:
ClassifierNode(classifier)

assert excinfo.value.args == ("Classifiers containing ':' are invalid",)