<commit_before>import html
import json
from collections import namedtuple
from copy import copy

from graphviz import ExecutableNotFound
from graphviz.dot import Digraph

from bonobo.constants import BEGIN
from bonobo.util import get_name

GraphRange = namedtuple("GraphRange", ["graph", "input", "output"])


class GraphCursor:
    @property
    def input(self):
        return self.first

    @property
    def output(self):
        return self.last

    def __init__(self, graph, *, first=None, last=None):
        self.graph = graph
        self.first = first or last
        self.last = last

    def __rshift__(self, other):
        """ Self >> Other """

        if other == ...:
            raise NotImplementedError(
                "Expected something looking like a node, but got an Ellipsis (...). Did you forget to complete the graph?"
            )

        nodes = other.nodes if hasattr(other, "nodes") else [other]

        if len(nodes):
            chain = self.graph.add_chain(*nodes, _input=self.last)
            return GraphCursor(chain.graph, first=self.first, last=chain.output)
<commit_msg>Complain if an elipsis is in the chain<commit_after>import html
import json
from collections import namedtuple
from copy import copy

from graphviz import ExecutableNotFound
from graphviz.dot import Digraph

from bonobo.constants import BEGIN
from bonobo.util import get_name

GraphRange = namedtuple("GraphRange", ["graph", "input", "output"])


class GraphCursor:
    @property
    def input(self):
        return self.first

    @property
    def output(self):
        return self.last

    def __init__(self, graph, *, first=None, last=None):
        self.graph = graph
        self.first = first or last
        self.last = last

    def __rshift__(self, other):
        """ Self >> Other """

        nodes = other.nodes if hasattr(other, "nodes") else [other]

        if ... in nodes:
            raise NotImplementedError(
                "Expected something looking like a node, but got an Ellipsis (...). Did you forget to complete the graph?"
            )


        if len(nodes):
            chain = self.graph.add_chain(*nodes, _input=self.last)
            return GraphCursor(chain.graph, first=self.first, last=chain.output)

{'fraction_non_alphanumeric': 0.09565987599645705, 'fraction_numerical': 0.0, 'mean_word_length': 2.626003210272873, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6403456', 'n_tokens_mistral': 632, 'n_tokens_neox': 612, 'n_words': 208}