Current File : //proc/self/root/usr/lib/python3/dist-packages/twisted/python/test/test_constants.py
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
Unit tests for L{twisted.python.constants}.
"""


import warnings

from twisted.trial.unittest import TestCase

with warnings.catch_warnings():
    warnings.simplefilter("ignore", category=DeprecationWarning)
    from twisted.python.constants import (
        FlagConstant,
        Flags,
        NamedConstant,
        Names,
        ValueConstant,
        Values,
    )


class NamedConstantTests(TestCase):
    """
    Tests for the L{twisted.python.constants.NamedConstant} class which is used
    to represent individual values.
    """

    def setUp(self):
        """
        Create a dummy container into which constants can be placed.
        """

        class foo(Names):
            pass

        self.container = foo

    def test_name(self):
        """
        The C{name} attribute of a L{NamedConstant} refers to the value passed
        for the C{name} parameter to C{_realize}.
        """
        name = NamedConstant()
        name._realize(self.container, "bar", None)
        self.assertEqual("bar", name.name)

    def test_representation(self):
        """
        The string representation of an instance of L{NamedConstant} includes
        the container the instances belongs to as well as the instance's name.
        """
        name = NamedConstant()
        name._realize(self.container, "bar", None)
        self.assertEqual("<foo=bar>", repr(name))

    def test_equality(self):
        """
        A L{NamedConstant} instance compares equal to itself.
        """
        name = NamedConstant()
        name._realize(self.container, "bar", None)
        self.assertTrue(name == name)
        self.assertFalse(name != name)

    def test_nonequality(self):
        """
        Two different L{NamedConstant} instances do not compare equal to each
        other.
        """
        first = NamedConstant()
        first._realize(self.container, "bar", None)
        second = NamedConstant()
        second._realize(self.container, "bar", None)
        self.assertFalse(first == second)
        self.assertTrue(first != second)

    def test_hash(self):
        """
        Because two different L{NamedConstant} instances do not compare as
        equal to each other, they also have different hashes to avoid
        collisions when added to a C{dict} or C{set}.
        """
        first = NamedConstant()
        first._realize(self.container, "bar", None)
        second = NamedConstant()
        second._realize(self.container, "bar", None)
        self.assertNotEqual(hash(first), hash(second))


class _ConstantsTestsMixin:
    """
    Mixin defining test helpers common to multiple types of constants
    collections.
    """

    def _notInstantiableTest(self, name, cls):
        """
        Assert that an attempt to instantiate the constants class raises
        C{TypeError}.

        @param name: A C{str} giving the name of the constants collection.
        @param cls: The constants class to test.
        """
        exc = self.assertRaises(TypeError, cls)
        self.assertEqual(name + " may not be instantiated.", str(exc))

    def _initializedOnceTest(self, container, constantName):
        """
        Assert that C{container._enumerants} does not change as a side-effect
        of one of its attributes being accessed.

        @param container: A L{_ConstantsContainer} subclass which will be
            tested.
        @param constantName: The name of one of the constants which is an
            attribute of C{container}.
        """
        first = container._enumerants

        # Accessing an attribute of the container should not have any
        # observable side-effect on the _enumerants attribute.
        getattr(container, constantName)

        second = container._enumerants
        self.assertIs(first, second)


class NamesTests(TestCase, _ConstantsTestsMixin):
    """
    Tests for L{twisted.python.constants.Names}, a base class for containers of
    related constraints.
    """

    def setUp(self):
        """
        Create a fresh new L{Names} subclass for each unit test to use.  Since
        L{Names} is stateful, re-using the same subclass across test methods
        makes exercising all of the implementation code paths difficult.
        """

        class METHOD(Names):
            """
            A container for some named constants to use in unit tests for
            L{Names}.
            """

            GET = NamedConstant()
            PUT = NamedConstant()
            POST = NamedConstant()
            DELETE = NamedConstant()

            extra = object()

        self.METHOD = METHOD

    def test_notInstantiable(self):
        """
        A subclass of L{Names} raises C{TypeError} if an attempt is made to
        instantiate it.
        """
        self._notInstantiableTest("METHOD", self.METHOD)

    def test_symbolicAttributes(self):
        """
        Each name associated with a L{NamedConstant} instance in the definition
        of a L{Names} subclass is available as an attribute on the resulting
        class.
        """
        self.assertTrue(hasattr(self.METHOD, "GET"))
        self.assertTrue(hasattr(self.METHOD, "PUT"))
        self.assertTrue(hasattr(self.METHOD, "POST"))
        self.assertTrue(hasattr(self.METHOD, "DELETE"))

    def test_withoutOtherAttributes(self):
        """
        As usual, names not defined in the class scope of a L{Names}
        subclass are not available as attributes on the resulting class.
        """
        self.assertFalse(hasattr(self.METHOD, "foo"))

    def test_representation(self):
        """
        The string representation of a constant on a L{Names} subclass includes
        the name of the L{Names} subclass and the name of the constant itself.
        """
        self.assertEqual("<METHOD=GET>", repr(self.METHOD.GET))

    def test_lookupByName(self):
        """
        Constants can be looked up by name using L{Names.lookupByName}.
        """
        method = self.METHOD.lookupByName("GET")
        self.assertIs(self.METHOD.GET, method)

    def test_notLookupMissingByName(self):
        """
        Names not defined with a L{NamedConstant} instance cannot be looked up
        using L{Names.lookupByName}.
        """
        self.assertRaises(ValueError, self.METHOD.lookupByName, "lookupByName")
        self.assertRaises(ValueError, self.METHOD.lookupByName, "__init__")
        self.assertRaises(ValueError, self.METHOD.lookupByName, "foo")
        self.assertRaises(ValueError, self.METHOD.lookupByName, "extra")

    def test_name(self):
        """
        The C{name} attribute of one of the named constants gives that
        constant's name.
        """
        self.assertEqual("GET", self.METHOD.GET.name)

    def test_attributeIdentity(self):
        """
        Repeated access of an attribute associated with a L{NamedConstant}
        value in a L{Names} subclass results in the same object.
        """
        self.assertIs(self.METHOD.GET, self.METHOD.GET)

    def test_iterconstants(self):
        """
        L{Names.iterconstants} returns an iterator over all of the constants
        defined in the class, in the order they were defined.
        """
        constants = list(self.METHOD.iterconstants())
        self.assertEqual(
            [self.METHOD.GET, self.METHOD.PUT, self.METHOD.POST, self.METHOD.DELETE],
            constants,
        )

    def test_attributeIterconstantsIdentity(self):
        """
        The constants returned from L{Names.iterconstants} are identical to the
        constants accessible using attributes.
        """
        constants = list(self.METHOD.iterconstants())
        self.assertIs(self.METHOD.GET, constants[0])
        self.assertIs(self.METHOD.PUT, constants[1])
        self.assertIs(self.METHOD.POST, constants[2])
        self.assertIs(self.METHOD.DELETE, constants[3])

    def test_iterconstantsIdentity(self):
        """
        The constants returned from L{Names.iterconstants} are identical on
        each call to that method.
        """
        constants = list(self.METHOD.iterconstants())
        again = list(self.METHOD.iterconstants())
        self.assertIs(again[0], constants[0])
        self.assertIs(again[1], constants[1])
        self.assertIs(again[2], constants[2])
        self.assertIs(again[3], constants[3])

    def test_initializedOnce(self):
        """
        L{Names._enumerants} is initialized once and its value re-used on
        subsequent access.
        """
        self._initializedOnceTest(self.METHOD, "GET")

    def test_asForeignClassAttribute(self):
        """
        A constant defined on a L{Names} subclass may be set as an attribute of
        another class and then retrieved using that attribute.
        """

        class Another:
            something = self.METHOD.GET

        self.assertIs(self.METHOD.GET, Another.something)

    def test_asForeignClassAttributeViaInstance(self):
        """
        A constant defined on a L{Names} subclass may be set as an attribute of
        another class and then retrieved from an instance of that class using
        that attribute.
        """

        class Another:
            something = self.METHOD.GET

        self.assertIs(self.METHOD.GET, Another().something)

    def test_notAsAlternateContainerAttribute(self):
        """
        It is explicitly disallowed (via a L{ValueError}) to use a constant
        defined on a L{Names} subclass as the value of an attribute of another
        L{Names} subclass.
        """

        def defineIt():
            class AnotherNames(Names):
                something = self.METHOD.GET

        exc = self.assertRaises(ValueError, defineIt)
        self.assertEqual(
            "Cannot use <METHOD=GET> as the value of an attribute on " "AnotherNames",
            str(exc),
        )


class ValuesTests(TestCase, _ConstantsTestsMixin):
    """
    Tests for L{twisted.python.constants.Names}, a base class for containers of
    related constraints with arbitrary values.
    """

    def setUp(self):
        """
        Create a fresh new L{Values} subclass for each unit test to use.  Since
        L{Values} is stateful, re-using the same subclass across test methods
        makes exercising all of the implementation code paths difficult.
        """

        class STATUS(Values):
            OK = ValueConstant("200")
            NOT_FOUND = ValueConstant("404")

        self.STATUS = STATUS

    def test_notInstantiable(self):
        """
        A subclass of L{Values} raises C{TypeError} if an attempt is made to
        instantiate it.
        """
        self._notInstantiableTest("STATUS", self.STATUS)

    def test_symbolicAttributes(self):
        """
        Each name associated with a L{ValueConstant} instance in the definition
        of a L{Values} subclass is available as an attribute on the resulting
        class.
        """
        self.assertTrue(hasattr(self.STATUS, "OK"))
        self.assertTrue(hasattr(self.STATUS, "NOT_FOUND"))

    def test_withoutOtherAttributes(self):
        """
        As usual, names not defined in the class scope of a L{Values}
        subclass are not available as attributes on the resulting class.
        """
        self.assertFalse(hasattr(self.STATUS, "foo"))

    def test_representation(self):
        """
        The string representation of a constant on a L{Values} subclass
        includes the name of the L{Values} subclass and the name of the
        constant itself.
        """
        self.assertEqual("<STATUS=OK>", repr(self.STATUS.OK))

    def test_lookupByName(self):
        """
        Constants can be looked up by name using L{Values.lookupByName}.
        """
        method = self.STATUS.lookupByName("OK")
        self.assertIs(self.STATUS.OK, method)

    def test_notLookupMissingByName(self):
        """
        Names not defined with a L{ValueConstant} instance cannot be looked up
        using L{Values.lookupByName}.
        """
        self.assertRaises(ValueError, self.STATUS.lookupByName, "lookupByName")
        self.assertRaises(ValueError, self.STATUS.lookupByName, "__init__")
        self.assertRaises(ValueError, self.STATUS.lookupByName, "foo")

    def test_lookupByValue(self):
        """
        Constants can be looked up by their associated value, defined by the
        argument passed to L{ValueConstant}, using L{Values.lookupByValue}.
        """
        status = self.STATUS.lookupByValue("200")
        self.assertIs(self.STATUS.OK, status)

    def test_lookupDuplicateByValue(self):
        """
        If more than one constant is associated with a particular value,
        L{Values.lookupByValue} returns whichever of them is defined first.
        """

        class TRANSPORT_MESSAGE(Values):
            """
            Message types supported by an SSH transport.
            """

            KEX_DH_GEX_REQUEST_OLD = ValueConstant(30)
            KEXDH_INIT = ValueConstant(30)

        self.assertIs(
            TRANSPORT_MESSAGE.lookupByValue(30),
            TRANSPORT_MESSAGE.KEX_DH_GEX_REQUEST_OLD,
        )

    def test_notLookupMissingByValue(self):
        """
        L{Values.lookupByValue} raises L{ValueError} when called with a value
        with which no constant is associated.
        """
        self.assertRaises(ValueError, self.STATUS.lookupByValue, "OK")
        self.assertRaises(ValueError, self.STATUS.lookupByValue, 200)
        self.assertRaises(ValueError, self.STATUS.lookupByValue, "200.1")

    def test_name(self):
        """
        The C{name} attribute of one of the constants gives that constant's
        name.
        """
        self.assertEqual("OK", self.STATUS.OK.name)

    def test_attributeIdentity(self):
        """
        Repeated access of an attribute associated with a L{ValueConstant}
        value in a L{Values} subclass results in the same object.
        """
        self.assertIs(self.STATUS.OK, self.STATUS.OK)

    def test_iterconstants(self):
        """
        L{Values.iterconstants} returns an iterator over all of the constants
        defined in the class, in the order they were defined.
        """
        constants = list(self.STATUS.iterconstants())
        self.assertEqual([self.STATUS.OK, self.STATUS.NOT_FOUND], constants)

    def test_attributeIterconstantsIdentity(self):
        """
        The constants returned from L{Values.iterconstants} are identical to
        the constants accessible using attributes.
        """
        constants = list(self.STATUS.iterconstants())
        self.assertIs(self.STATUS.OK, constants[0])
        self.assertIs(self.STATUS.NOT_FOUND, constants[1])

    def test_iterconstantsIdentity(self):
        """
        The constants returned from L{Values.iterconstants} are identical on
        each call to that method.
        """
        constants = list(self.STATUS.iterconstants())
        again = list(self.STATUS.iterconstants())
        self.assertIs(again[0], constants[0])
        self.assertIs(again[1], constants[1])

    def test_initializedOnce(self):
        """
        L{Values._enumerants} is initialized once and its value re-used on
        subsequent access.
        """
        self._initializedOnceTest(self.STATUS, "OK")


class _FlagsTestsMixin:
    """
    Mixin defining setup code for any tests for L{Flags} subclasses.

    @ivar FXF: A L{Flags} subclass created for each test method.
    """

    def setUp(self):
        """
        Create a fresh new L{Flags} subclass for each unit test to use.  Since
        L{Flags} is stateful, re-using the same subclass across test methods
        makes exercising all of the implementation code paths difficult.
        """

        class FXF(Flags):
            # Implicitly assign three flag values based on definition order
            READ = FlagConstant()
            WRITE = FlagConstant()
            APPEND = FlagConstant()

            # Explicitly assign one flag value by passing it in
            EXCLUSIVE = FlagConstant(0x20)

            # Implicitly assign another flag value, following the previously
            # specified explicit value.
            TEXT = FlagConstant()

        self.FXF = FXF


class FlagsTests(_FlagsTestsMixin, TestCase, _ConstantsTestsMixin):
    """
    Tests for L{twisted.python.constants.Flags}, a base class for containers of
    related, combinable flag or bitvector-like constants.
    """

    def test_notInstantiable(self):
        """
        A subclass of L{Flags} raises L{TypeError} if an attempt is made to
        instantiate it.
        """
        self._notInstantiableTest("FXF", self.FXF)

    def test_symbolicAttributes(self):
        """
        Each name associated with a L{FlagConstant} instance in the definition
        of a L{Flags} subclass is available as an attribute on the resulting
        class.
        """
        self.assertTrue(hasattr(self.FXF, "READ"))
        self.assertTrue(hasattr(self.FXF, "WRITE"))
        self.assertTrue(hasattr(self.FXF, "APPEND"))
        self.assertTrue(hasattr(self.FXF, "EXCLUSIVE"))
        self.assertTrue(hasattr(self.FXF, "TEXT"))

    def test_withoutOtherAttributes(self):
        """
        As usual, names not defined in the class scope of a L{Flags} subclass
        are not available as attributes on the resulting class.
        """
        self.assertFalse(hasattr(self.FXF, "foo"))

    def test_representation(self):
        """
        The string representation of a constant on a L{Flags} subclass includes
        the name of the L{Flags} subclass and the name of the constant itself.
        """
        self.assertEqual("<FXF=READ>", repr(self.FXF.READ))

    def test_lookupByName(self):
        """
        Constants can be looked up by name using L{Flags.lookupByName}.
        """
        flag = self.FXF.lookupByName("READ")
        self.assertIs(self.FXF.READ, flag)

    def test_notLookupMissingByName(self):
        """
        Names not defined with a L{FlagConstant} instance cannot be looked up
        using L{Flags.lookupByName}.
        """
        self.assertRaises(ValueError, self.FXF.lookupByName, "lookupByName")
        self.assertRaises(ValueError, self.FXF.lookupByName, "__init__")
        self.assertRaises(ValueError, self.FXF.lookupByName, "foo")

    def test_lookupByValue(self):
        """
        Constants can be looked up by their associated value, defined
        implicitly by the position in which the constant appears in the class
        definition or explicitly by the argument passed to L{FlagConstant}.
        """
        flag = self.FXF.lookupByValue(0x01)
        self.assertIs(flag, self.FXF.READ)

        flag = self.FXF.lookupByValue(0x02)
        self.assertIs(flag, self.FXF.WRITE)

        flag = self.FXF.lookupByValue(0x04)
        self.assertIs(flag, self.FXF.APPEND)

        flag = self.FXF.lookupByValue(0x20)
        self.assertIs(flag, self.FXF.EXCLUSIVE)

        flag = self.FXF.lookupByValue(0x40)
        self.assertIs(flag, self.FXF.TEXT)

    def test_lookupDuplicateByValue(self):
        """
        If more than one constant is associated with a particular value,
        L{Flags.lookupByValue} returns whichever of them is defined first.
        """

        class TIMEX(Flags):
            # (timex.mode)
            ADJ_OFFSET = FlagConstant(0x0001)  # time offset

            #  xntp 3.4 compatibility names
            MOD_OFFSET = FlagConstant(0x0001)

        self.assertIs(TIMEX.lookupByValue(0x0001), TIMEX.ADJ_OFFSET)

    def test_notLookupMissingByValue(self):
        """
        L{Flags.lookupByValue} raises L{ValueError} when called with a value
        with which no constant is associated.
        """
        self.assertRaises(ValueError, self.FXF.lookupByValue, 0x10)

    def test_name(self):
        """
        The C{name} attribute of one of the constants gives that constant's
        name.
        """
        self.assertEqual("READ", self.FXF.READ.name)

    def test_attributeIdentity(self):
        """
        Repeated access of an attribute associated with a L{FlagConstant} value
        in a L{Flags} subclass results in the same object.
        """
        self.assertIs(self.FXF.READ, self.FXF.READ)

    def test_iterconstants(self):
        """
        L{Flags.iterconstants} returns an iterator over all of the constants
        defined in the class, in the order they were defined.
        """
        constants = list(self.FXF.iterconstants())
        self.assertEqual(
            [
                self.FXF.READ,
                self.FXF.WRITE,
                self.FXF.APPEND,
                self.FXF.EXCLUSIVE,
                self.FXF.TEXT,
            ],
            constants,
        )

    def test_attributeIterconstantsIdentity(self):
        """
        The constants returned from L{Flags.iterconstants} are identical to the
        constants accessible using attributes.
        """
        constants = list(self.FXF.iterconstants())
        self.assertIs(self.FXF.READ, constants[0])
        self.assertIs(self.FXF.WRITE, constants[1])
        self.assertIs(self.FXF.APPEND, constants[2])
        self.assertIs(self.FXF.EXCLUSIVE, constants[3])
        self.assertIs(self.FXF.TEXT, constants[4])

    def test_iterconstantsIdentity(self):
        """
        The constants returned from L{Flags.iterconstants} are identical on
        each call to that method.
        """
        constants = list(self.FXF.iterconstants())
        again = list(self.FXF.iterconstants())
        self.assertIs(again[0], constants[0])
        self.assertIs(again[1], constants[1])
        self.assertIs(again[2], constants[2])
        self.assertIs(again[3], constants[3])
        self.assertIs(again[4], constants[4])

    def test_initializedOnce(self):
        """
        L{Flags._enumerants} is initialized once and its value re-used on
        subsequent access.
        """
        self._initializedOnceTest(self.FXF, "READ")


class FlagConstantSimpleOrTests(_FlagsTestsMixin, TestCase):
    """
    Tests for the C{|} operator as defined for L{FlagConstant} instances, used
    to create new L{FlagConstant} instances representing both of two existing
    L{FlagConstant} instances from the same L{Flags} class.
    """

    def test_value(self):
        """
        The value of the L{FlagConstant} which results from C{|} has all of the
        bits set which were set in either of the values of the two original
        constants.
        """
        flag = self.FXF.READ | self.FXF.WRITE
        self.assertEqual(self.FXF.READ.value | self.FXF.WRITE.value, flag.value)

    def test_name(self):
        """
        The name of the L{FlagConstant} instance which results from C{|}
        includes the names of both of the two original constants.
        """
        flag = self.FXF.READ | self.FXF.WRITE
        self.assertEqual("{READ,WRITE}", flag.name)

    def test_representation(self):
        """
        The string representation of a L{FlagConstant} instance which results
        from C{|} includes the names of both of the two original constants.
        """
        flag = self.FXF.READ | self.FXF.WRITE
        self.assertEqual("<FXF={READ,WRITE}>", repr(flag))

    def test_iterate(self):
        """
        A L{FlagConstant} instance which results from C{|} can be
        iterated upon to yield the original constants.
        """
        self.assertEqual(set(self.FXF.WRITE & self.FXF.READ), set())  # No flags
        self.assertEqual(set(self.FXF.WRITE), {self.FXF.WRITE})
        self.assertEqual(
            set(self.FXF.WRITE | self.FXF.EXCLUSIVE),
            {self.FXF.WRITE, self.FXF.EXCLUSIVE},
        )

    def test_membership(self):
        """
        A L{FlagConstant} instance which results from C{|} can be
        tested for membership.
        """
        flags = self.FXF.WRITE | self.FXF.EXCLUSIVE
        self.assertIn(self.FXF.WRITE, flags)
        self.assertNotIn(self.FXF.READ, flags)

    def test_truthiness(self):
        """
        Empty flags is false, non-empty flags is true.
        """
        self.assertTrue(self.FXF.WRITE)
        self.assertTrue(self.FXF.WRITE | self.FXF.EXCLUSIVE)
        self.assertFalse(self.FXF.WRITE & self.FXF.EXCLUSIVE)


class FlagConstantSimpleAndTests(_FlagsTestsMixin, TestCase):
    """
    Tests for the C{&} operator as defined for L{FlagConstant} instances, used
    to create new L{FlagConstant} instances representing the common parts of
    two existing L{FlagConstant} instances from the same L{Flags} class.
    """

    def test_value(self):
        """
        The value of the L{FlagConstant} which results from C{&} has all of the
        bits set which were set in both of the values of the two original
        constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite & writeAppend
        self.assertEqual(self.FXF.WRITE.value, flag.value)

    def test_name(self):
        """
        The name of the L{FlagConstant} instance which results from C{&}
        includes the names of only the flags which were set in both of the two
        original constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite & writeAppend
        self.assertEqual("WRITE", flag.name)

    def test_representation(self):
        """
        The string representation of a L{FlagConstant} instance which results
        from C{&} includes the names of only the flags which were set in both
        both of the two original constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite & writeAppend
        self.assertEqual("<FXF=WRITE>", repr(flag))


class FlagConstantSimpleExclusiveOrTests(_FlagsTestsMixin, TestCase):
    """
    Tests for the C{^} operator as defined for L{FlagConstant} instances, used
    to create new L{FlagConstant} instances representing the uncommon parts of
    two existing L{FlagConstant} instances from the same L{Flags} class.
    """

    def test_value(self):
        """
        The value of the L{FlagConstant} which results from C{^} has all of the
        bits set which were set in exactly one of the values of the two
        original constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite ^ writeAppend
        self.assertEqual(self.FXF.READ.value | self.FXF.APPEND.value, flag.value)

    def test_name(self):
        """
        The name of the L{FlagConstant} instance which results from C{^}
        includes the names of only the flags which were set in exactly one of
        the two original constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite ^ writeAppend
        self.assertEqual("{APPEND,READ}", flag.name)

    def test_representation(self):
        """
        The string representation of a L{FlagConstant} instance which results
        from C{^} includes the names of only the flags which were set in
        exactly one of the two original constants.
        """
        readWrite = self.FXF.READ | self.FXF.WRITE
        writeAppend = self.FXF.WRITE | self.FXF.APPEND
        flag = readWrite ^ writeAppend
        self.assertEqual("<FXF={APPEND,READ}>", repr(flag))


class FlagConstantNegationTests(_FlagsTestsMixin, TestCase):
    """
    Tests for the C{~} operator as defined for L{FlagConstant} instances, used
    to create new L{FlagConstant} instances representing all the flags from a
    L{Flags} class not set in a particular L{FlagConstant} instance.
    """

    def test_value(self):
        """
        The value of the L{FlagConstant} which results from C{~} has all of the
        bits set which were not set in the original constant.
        """
        flag = ~self.FXF.READ
        self.assertEqual(
            self.FXF.WRITE.value
            | self.FXF.APPEND.value
            | self.FXF.EXCLUSIVE.value
            | self.FXF.TEXT.value,
            flag.value,
        )

        flag = ~self.FXF.WRITE
        self.assertEqual(
            self.FXF.READ.value
            | self.FXF.APPEND.value
            | self.FXF.EXCLUSIVE.value
            | self.FXF.TEXT.value,
            flag.value,
        )

    def test_name(self):
        """
        The name of the L{FlagConstant} instance which results from C{~}
        includes the names of all the flags which were not set in the original
        constant.
        """
        flag = ~self.FXF.WRITE
        self.assertEqual("{APPEND,EXCLUSIVE,READ,TEXT}", flag.name)

    def test_representation(self):
        """
        The string representation of a L{FlagConstant} instance which results
        from C{~} includes the names of all the flags which were not set in the
        original constant.
        """
        flag = ~self.FXF.WRITE
        self.assertEqual("<FXF={APPEND,EXCLUSIVE,READ,TEXT}>", repr(flag))


class OrderedConstantsTests(TestCase):
    """
    Tests for the ordering of constants.  All constants are ordered by
    the order in which they are defined in their container class.
    The ordering of constants that are not in the same container is not
    defined.
    """

    def test_orderedNameConstants_lt(self):
        """
        L{twisted.python.constants.NamedConstant} preserves definition
        order in C{<} comparisons.
        """
        self.assertTrue(NamedLetters.alpha < NamedLetters.beta)

    def test_orderedNameConstants_le(self):
        """
        L{twisted.python.constants.NamedConstant} preserves definition
        order in C{<=} comparisons.
        """
        self.assertTrue(NamedLetters.alpha <= NamedLetters.alpha)
        self.assertTrue(NamedLetters.alpha <= NamedLetters.beta)

    def test_orderedNameConstants_gt(self):
        """
        L{twisted.python.constants.NamedConstant} preserves definition
        order in C{>} comparisons.
        """
        self.assertTrue(NamedLetters.beta > NamedLetters.alpha)

    def test_orderedNameConstants_ge(self):
        """
        L{twisted.python.constants.NamedConstant} preserves definition
        order in C{>=} comparisons.
        """
        self.assertTrue(NamedLetters.alpha >= NamedLetters.alpha)
        self.assertTrue(NamedLetters.beta >= NamedLetters.alpha)

    def test_orderedValueConstants_lt(self):
        """
        L{twisted.python.constants.ValueConstant} preserves definition
        order in C{<} comparisons.
        """
        self.assertTrue(ValuedLetters.alpha < ValuedLetters.digamma)
        self.assertTrue(ValuedLetters.digamma < ValuedLetters.zeta)

    def test_orderedValueConstants_le(self):
        """
        L{twisted.python.constants.ValueConstant} preserves definition
        order in C{<=} comparisons.
        """
        self.assertTrue(ValuedLetters.alpha <= ValuedLetters.alpha)
        self.assertTrue(ValuedLetters.alpha <= ValuedLetters.digamma)
        self.assertTrue(ValuedLetters.digamma <= ValuedLetters.zeta)

    def test_orderedValueConstants_gt(self):
        """
        L{twisted.python.constants.ValueConstant} preserves definition
        order in C{>} comparisons.
        """
        self.assertTrue(ValuedLetters.digamma > ValuedLetters.alpha)
        self.assertTrue(ValuedLetters.zeta > ValuedLetters.digamma)

    def test_orderedValueConstants_ge(self):
        """
        L{twisted.python.constants.ValueConstant} preserves definition
        order in C{>=} comparisons.
        """
        self.assertTrue(ValuedLetters.alpha >= ValuedLetters.alpha)
        self.assertTrue(ValuedLetters.digamma >= ValuedLetters.alpha)
        self.assertTrue(ValuedLetters.zeta >= ValuedLetters.digamma)

    def test_orderedFlagConstants_lt(self):
        """
        L{twisted.python.constants.FlagConstant} preserves definition
        order in C{<} comparisons.
        """
        self.assertTrue(PizzaToppings.mozzarella < PizzaToppings.pesto)
        self.assertTrue(PizzaToppings.pesto < PizzaToppings.pepperoni)

    def test_orderedFlagConstants_le(self):
        """
        L{twisted.python.constants.FlagConstant} preserves definition
        order in C{<=} comparisons.
        """
        self.assertTrue(PizzaToppings.mozzarella <= PizzaToppings.mozzarella)
        self.assertTrue(PizzaToppings.mozzarella <= PizzaToppings.pesto)
        self.assertTrue(PizzaToppings.pesto <= PizzaToppings.pepperoni)

    def test_orderedFlagConstants_gt(self):
        """
        L{twisted.python.constants.FlagConstant} preserves definition
        order in C{>} comparisons.
        """
        self.assertTrue(PizzaToppings.pesto > PizzaToppings.mozzarella)
        self.assertTrue(PizzaToppings.pepperoni > PizzaToppings.pesto)

    def test_orderedFlagConstants_ge(self):
        """
        L{twisted.python.constants.FlagConstant} preserves definition
        order in C{>=} comparisons.
        """
        self.assertTrue(PizzaToppings.mozzarella >= PizzaToppings.mozzarella)
        self.assertTrue(PizzaToppings.pesto >= PizzaToppings.mozzarella)
        self.assertTrue(PizzaToppings.pepperoni >= PizzaToppings.pesto)

    def test_orderedDifferentConstants_lt(self):
        """
        L{twisted.python.constants._Constant.__lt__} returns C{NotImplemented}
        when comparing constants of different types.
        """
        self.assertEqual(NotImplemented, NamedLetters.alpha.__lt__(ValuedLetters.alpha))

    def test_orderedDifferentConstants_le(self):
        """
        L{twisted.python.constants._Constant.__le__} returns C{NotImplemented}
        when comparing constants of different types.
        """
        self.assertEqual(NotImplemented, NamedLetters.alpha.__le__(ValuedLetters.alpha))

    def test_orderedDifferentConstants_gt(self):
        """
        L{twisted.python.constants._Constant.__gt__} returns C{NotImplemented}
        when comparing constants of different types.
        """
        self.assertEqual(NotImplemented, NamedLetters.alpha.__gt__(ValuedLetters.alpha))

    def test_orderedDifferentConstants_ge(self):
        """
        L{twisted.python.constants._Constant.__ge__} returns C{NotImplemented}
        when comparing constants of different types.
        """
        self.assertEqual(NotImplemented, NamedLetters.alpha.__ge__(ValuedLetters.alpha))

    def test_orderedDifferentContainers_lt(self):
        """
        L{twisted.python.constants._Constant.__lt__} returns C{NotImplemented}
        when comparing constants belonging to different containers.
        """
        self.assertEqual(
            NotImplemented, NamedLetters.alpha.__lt__(MoreNamedLetters.digamma)
        )

    def test_orderedDifferentContainers_le(self):
        """
        L{twisted.python.constants._Constant.__le__} returns C{NotImplemented}
        when comparing constants belonging to different containers.
        """
        self.assertEqual(
            NotImplemented, NamedLetters.alpha.__le__(MoreNamedLetters.digamma)
        )

    def test_orderedDifferentContainers_gt(self):
        """
        L{twisted.python.constants._Constant.__gt__} returns C{NotImplemented}
        when comparing constants belonging to different containers.
        """
        self.assertEqual(
            NotImplemented, NamedLetters.alpha.__gt__(MoreNamedLetters.digamma)
        )

    def test_orderedDifferentContainers_ge(self):
        """
        L{twisted.python.constants._Constant.__ge__} returns C{NotImplemented}
        when comparing constants belonging to different containers.
        """
        self.assertEqual(
            NotImplemented, NamedLetters.alpha.__ge__(MoreNamedLetters.digamma)
        )


class NamedLetters(Names):
    """
    Some letters, named.
    """

    alpha = NamedConstant()
    beta = NamedConstant()


class MoreNamedLetters(Names):
    """
    Some more letters, named.
    """

    digamma = NamedConstant()
    zeta = NamedConstant()


class ValuedLetters(Values):
    """
    Some more letters, with corresponding unicode values.
    """

    # Note u'\u0391' < u'\u03dc' > u'\u0396'.  We are ensuring here that the
    # definition is order different from the order of the values, which lets us
    # test that we're not somehow ordering by value and happen the get the same
    # results.
    alpha = ValueConstant("\u0391")
    digamma = ValueConstant("\u03dc")
    zeta = ValueConstant("\u0396")


class PizzaToppings(Flags):
    """
    Some pizza toppings, with obviously meaningful bitwise values.
    """

    # Note 1<<1 < 1<<4 > 1<<2, so we are ensuring here that the definition
    # order is different from the order of the values, which lets us test that
    # we're not somehow ordering by value and happen the get the same results.
    mozzarella = FlagConstant(1 << 1)
    pesto = FlagConstant(1 << 4)
    pepperoni = FlagConstant(1 << 2)


class ConstantsDeprecationTests(TestCase):
    """
    L{twisted.python.constants} is deprecated.
    """

    def test_constantsDeprecation(self):
        """
        L{twisted.python.constants} is deprecated since Twisted 16.5.
        """
        from twisted.python import constants

        constants

        warningsShown = self.flushWarnings([self.test_constantsDeprecation])
        self.assertEqual(1, len(warningsShown))
        self.assertEqual(
            (
                "twisted.python.constants was deprecated in Twisted 16.5.0: "
                "Please use constantly from PyPI instead."
            ),
            warningsShown[0]["message"],
        )
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!