././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6352432
constantly-23.10.4/ 0000755 0000765 0000024 00000000000 14517313232 013126 5 ustar 00glyph staff ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/CREDITS 0000644 0000765 0000024 00000000127 13641305077 014153 0 ustar 00glyph staff Amber Hawkie Brown
Glyph Lefkowitz
Jean-Paul Calderone
Richard Wall
Wilfredo Sánchez
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/LICENSE 0000644 0000765 0000024 00000002134 13641305077 014140 0 ustar 00glyph staff Copyright (c) 2011-2015 Twisted Matrix Laboratories &
Individual Contributors (see CREDITS)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/MANIFEST.in 0000644 0000765 0000024 00000000150 13641305077 014665 0 ustar 00glyph staff include versioneer.py
include constantly/_version.py
include README.rst
include LICENSE
include CREDITS
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6350608
constantly-23.10.4/PKG-INFO 0000644 0000765 0000024 00000003343 14517313232 014226 0 ustar 00glyph staff Metadata-Version: 2.1
Name: constantly
Version: 23.10.4
Summary: Symbolic constants in Python
Maintainer: Twisted Matrix Labs Developers
License: MIT
Project-URL: Homepage, https://github.com/twisted/constantly
Keywords: constants,enum,twisted
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
License-File: LICENSE
Constantly
==========
A library that provides symbolic constant support. It includes collections and
constants with text, numeric, and bit flag values. Originally
``twisted.python.constants`` from the `Twisted `_
project.
Installing
----------
constantly is available in `PyPI `_, and
can be installed via pip::
$ pip install constantly
Documentation
-------------------------
Documentation is available at ``_.
Tests
-----
To run tests::
$ tox
This will run tests on Python 2.7, 3.3, 3.4, and PyPy, as well as doing
coverage and pyflakes checks.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698534902.0
constantly-23.10.4/README.rst 0000644 0000765 0000024 00000001250 14517312766 014626 0 ustar 00glyph staff Constantly
==========
A library that provides symbolic constant support. It includes collections and
constants with text, numeric, and bit flag values. Originally
``twisted.python.constants`` from the `Twisted `_
project.
Installing
----------
constantly is available in `PyPI `_, and
can be installed via pip::
$ pip install constantly
Documentation
-------------------------
Documentation is available at ``_.
Tests
-----
To run tests::
$ tox
This will run tests on Python 2.7, 3.3, 3.4, and PyPy, as well as doing
coverage and pyflakes checks.
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6341403
constantly-23.10.4/constantly/ 0000755 0000765 0000024 00000000000 14517313232 015324 5 ustar 00glyph staff ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698532976.0
constantly-23.10.4/constantly/__init__.py 0000644 0000765 0000024 00000000761 14517307160 017444 0 ustar 00glyph staff # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
from constantly._constants import (
NamedConstant, Names, ValueConstant, Values, FlagConstant, Flags
)
from . import _version
__version__ = _version.get_versions()['version']
__author__ = "Twisted Matrix Laboratories"
__license__ = "MIT"
__copyright__ = "Copyright 2011-2015 {0}".format(__author__)
__all__ = [
'NamedConstant',
'ValueConstant',
'FlagConstant',
'Names',
'Values',
'Flags',
]
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/constantly/_constants.py 0000644 0000765 0000024 00000037205 13641305077 020065 0 ustar 00glyph staff # -*- test-case-name: constantly.test.test_constants -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Symbolic constant support, including collections and constants with text,
numeric, and bit flag values.
"""
from __future__ import division, absolute_import
__all__ = []
from functools import partial
from itertools import count
from operator import and_, or_, xor
_unspecified = object()
_constantOrder = partial(next, count())
class _Constant(object):
"""
@ivar _index: A C{int} allocated from a shared counter in order to keep
track of the order in which L{_Constant}s are instantiated.
@ivar name: A C{str} giving the name of this constant; only set once the
constant is initialized by L{_ConstantsContainer}.
@ivar _container: The L{_ConstantsContainer} subclass this constant belongs
to; C{None} until the constant is initialized by that subclass.
"""
def __init__(self):
self._container = None
self._index = _constantOrder()
def __repr__(self):
"""
Return text identifying both which constant this is and which
collection it belongs to.
"""
return "<%s=%s>" % (self._container.__name__, self.name)
def __lt__(self, other):
"""
Implements C{<}. Order is defined by instantiation order.
@param other: An object.
@return: C{NotImplemented} if C{other} is not a constant belonging to
the same container as this constant, C{True} if this constant is
defined before C{other}, otherwise C{False}.
"""
if (
not isinstance(other, self.__class__) or
not self._container == other._container
):
return NotImplemented
return self._index < other._index
def __le__(self, other):
"""
Implements C{<=}. Order is defined by instantiation order.
@param other: An object.
@return: C{NotImplemented} if C{other} is not a constant belonging to
the same container as this constant, C{True} if this constant is
defined before or equal to C{other}, otherwise C{False}.
"""
if (
not isinstance(other, self.__class__) or
not self._container == other._container
):
return NotImplemented
return self is other or self._index < other._index
def __gt__(self, other):
"""
Implements C{>}. Order is defined by instantiation order.
@param other: An object.
@return: C{NotImplemented} if C{other} is not a constant belonging to
the same container as this constant, C{True} if this constant is
defined after C{other}, otherwise C{False}.
"""
if (
not isinstance(other, self.__class__) or
not self._container == other._container
):
return NotImplemented
return self._index > other._index
def __ge__(self, other):
"""
Implements C{>=}. Order is defined by instantiation order.
@param other: An object.
@return: C{NotImplemented} if C{other} is not a constant belonging to
the same container as this constant, C{True} if this constant is
defined after or equal to C{other}, otherwise C{False}.
"""
if (
not isinstance(other, self.__class__) or
not self._container == other._container
):
return NotImplemented
return self is other or self._index > other._index
def _realize(self, container, name, value):
"""
Complete the initialization of this L{_Constant}.
@param container: The L{_ConstantsContainer} subclass this constant is
part of.
@param name: The name of this constant in its container.
@param value: The value of this constant; not used, as named constants
have no value apart from their identity.
"""
self._container = container
self.name = name
class _ConstantsContainerType(type):
"""
L{_ConstantsContainerType} is a metaclass for creating constants container
classes.
"""
def __new__(self, name, bases, attributes):
"""
Create a new constants container class.
If C{attributes} includes a value of C{None} for the C{"_constantType"}
key, the new class will not be initialized as a constants container and
it will behave as a normal class.
@param name: The name of the container class.
@type name: L{str}
@param bases: A tuple of the base classes for the new container class.
@type bases: L{tuple} of L{_ConstantsContainerType} instances
@param attributes: The attributes of the new container class, including
any constants it is to contain.
@type attributes: L{dict}
"""
cls = super(_ConstantsContainerType, self).__new__(
self, name, bases, attributes)
# Only realize constants in concrete _ConstantsContainer subclasses.
# Ignore intermediate base classes.
constantType = getattr(cls, '_constantType', None)
if constantType is None:
return cls
constants = []
for (name, descriptor) in attributes.items():
if isinstance(descriptor, cls._constantType):
if descriptor._container is not None:
raise ValueError(
"Cannot use %s as the value of an attribute on %s" % (
descriptor, cls.__name__))
constants.append((descriptor._index, name, descriptor))
enumerants = {}
for (index, enumerant, descriptor) in sorted(constants):
value = cls._constantFactory(enumerant, descriptor)
descriptor._realize(cls, enumerant, value)
enumerants[enumerant] = descriptor
# Save the dictionary which contains *only* constants (distinct from
# any other attributes the application may have given the container)
# where the class can use it later (eg for lookupByName).
cls._enumerants = enumerants
return cls
# In Python3 metaclasses are defined using a C{metaclass} keyword argument in
# the class definition. This would cause a syntax error in Python2.
# So we use L{type} to introduce an intermediate base class with the desired
# metaclass.
# See:
# * http://docs.python.org/2/library/functions.html#type
# * http://docs.python.org/3/reference/datamodel.html#customizing-class-creation
class _ConstantsContainer(_ConstantsContainerType('', (object,), {})):
"""
L{_ConstantsContainer} is a class with attributes used as symbolic
constants. It is up to subclasses to specify what kind of constants are
allowed.
@cvar _constantType: Specified by a L{_ConstantsContainer} subclass to
specify the type of constants allowed by that subclass.
@cvar _enumerants: A C{dict} mapping the names of constants (eg
L{NamedConstant} instances) found in the class definition to those
instances.
"""
_constantType = None
def __new__(cls):
"""
Classes representing constants containers are not intended to be
instantiated.
The class object itself is used directly.
"""
raise TypeError("%s may not be instantiated." % (cls.__name__,))
@classmethod
def _constantFactory(cls, name, descriptor):
"""
Construct the value for a new constant to add to this container.
@param name: The name of the constant to create.
@param descriptor: An instance of a L{_Constant} subclass (eg
L{NamedConstant}) which is assigned to C{name}.
@return: L{NamedConstant} instances have no value apart from identity,
so return a meaningless dummy value.
"""
return _unspecified
@classmethod
def lookupByName(cls, name):
"""
Retrieve a constant by its name or raise a C{ValueError} if there is no
constant associated with that name.
@param name: A C{str} giving the name of one of the constants defined
by C{cls}.
@raise ValueError: If C{name} is not the name of one of the constants
defined by C{cls}.
@return: The L{NamedConstant} associated with C{name}.
"""
if name in cls._enumerants:
return getattr(cls, name)
raise ValueError(name)
@classmethod
def iterconstants(cls):
"""
Iteration over a L{Names} subclass results in all of the constants it
contains.
@return: an iterator the elements of which are the L{NamedConstant}
instances defined in the body of this L{Names} subclass.
"""
constants = cls._enumerants.values()
return iter(
sorted(constants, key=lambda descriptor: descriptor._index))
class NamedConstant(_Constant):
"""
L{NamedConstant} defines an attribute to be a named constant within a
collection defined by a L{Names} subclass.
L{NamedConstant} is only for use in the definition of L{Names}
subclasses. Do not instantiate L{NamedConstant} elsewhere and do not
subclass it.
"""
class Names(_ConstantsContainer):
"""
A L{Names} subclass contains constants which differ only in their names and
identities.
"""
_constantType = NamedConstant
class ValueConstant(_Constant):
"""
L{ValueConstant} defines an attribute to be a named constant within a
collection defined by a L{Values} subclass.
L{ValueConstant} is only for use in the definition of L{Values} subclasses.
Do not instantiate L{ValueConstant} elsewhere and do not subclass it.
"""
def __init__(self, value):
_Constant.__init__(self)
self.value = value
class Values(_ConstantsContainer):
"""
A L{Values} subclass contains constants which are associated with arbitrary
values.
"""
_constantType = ValueConstant
@classmethod
def lookupByValue(cls, value):
"""
Retrieve a constant by its value or raise a C{ValueError} if there is
no constant associated with that value.
@param value: The value of one of the constants defined by C{cls}.
@raise ValueError: If C{value} is not the value of one of the constants
defined by C{cls}.
@return: The L{ValueConstant} associated with C{value}.
"""
for constant in cls.iterconstants():
if constant.value == value:
return constant
raise ValueError(value)
def _flagOp(op, left, right):
"""
Implement a binary operator for a L{FlagConstant} instance.
@param op: A two-argument callable implementing the binary operation. For
example, C{operator.or_}.
@param left: The left-hand L{FlagConstant} instance.
@param right: The right-hand L{FlagConstant} instance.
@return: A new L{FlagConstant} instance representing the result of the
operation.
"""
value = op(left.value, right.value)
names = op(left.names, right.names)
result = FlagConstant()
result._realize(left._container, names, value)
return result
class FlagConstant(_Constant):
"""
L{FlagConstant} defines an attribute to be a flag constant within a
collection defined by a L{Flags} subclass.
L{FlagConstant} is only for use in the definition of L{Flags} subclasses.
Do not instantiate L{FlagConstant} elsewhere and do not subclass it.
"""
def __init__(self, value=_unspecified):
_Constant.__init__(self)
self.value = value
def _realize(self, container, names, value):
"""
Complete the initialization of this L{FlagConstant}.
This implementation differs from other C{_realize} implementations in
that a L{FlagConstant} may have several names which apply to it, due to
flags being combined with various operators.
@param container: The L{Flags} subclass this constant is part of.
@param names: When a single-flag value is being initialized, a C{str}
giving the name of that flag. This is the case which happens when
a L{Flags} subclass is being initialized and L{FlagConstant}
instances from its body are being realized. Otherwise, a C{set} of
C{str} giving names of all the flags set on this L{FlagConstant}
instance. This is the case when two flags are combined using C{|},
for example.
"""
if isinstance(names, str):
name = names
names = set([names])
elif len(names) == 1:
(name,) = names
else:
name = "{" + ",".join(sorted(names)) + "}"
_Constant._realize(self, container, name, value)
self.value = value
self.names = names
def __or__(self, other):
"""
Define C{|} on two L{FlagConstant} instances to create a new
L{FlagConstant} instance with all flags set in either instance set.
"""
return _flagOp(or_, self, other)
def __and__(self, other):
"""
Define C{&} on two L{FlagConstant} instances to create a new
L{FlagConstant} instance with only flags set in both instances set.
"""
return _flagOp(and_, self, other)
def __xor__(self, other):
"""
Define C{^} on two L{FlagConstant} instances to create a new
L{FlagConstant} instance with only flags set on exactly one instance
set.
"""
return _flagOp(xor, self, other)
def __invert__(self):
"""
Define C{~} on a L{FlagConstant} instance to create a new
L{FlagConstant} instance with all flags not set on this instance set.
"""
result = FlagConstant()
result._realize(self._container, set(), 0)
for flag in self._container.iterconstants():
if flag.value & self.value == 0:
result |= flag
return result
def __iter__(self):
"""
@return: An iterator of flags set on this instance set.
"""
return (self._container.lookupByName(name) for name in self.names)
def __contains__(self, flag):
"""
@param flag: The flag to test for membership in this instance
set.
@return: C{True} if C{flag} is in this instance set, else
C{False}.
"""
# Optimization for testing membership without iteration.
return bool(flag & self)
def __nonzero__(self):
"""
@return: C{False} if this flag's value is 0, else C{True}.
"""
return bool(self.value)
__bool__ = __nonzero__
class Flags(Values):
"""
A L{Flags} subclass contains constants which can be combined using the
common bitwise operators (C{|}, C{&}, etc) similar to a I{bitvector} from a
language like C.
"""
_constantType = FlagConstant
_value = 1
@classmethod
def _constantFactory(cls, name, descriptor):
"""
For L{FlagConstant} instances with no explicitly defined value, assign
the next power of two as its value.
@param name: The name of the constant to create.
@param descriptor: An instance of a L{FlagConstant} which is assigned
to C{name}.
@return: Either the value passed to the C{descriptor} constructor, or
the next power of 2 value which will be assigned to C{descriptor},
relative to the value of the last defined L{FlagConstant}.
"""
if descriptor.value is _unspecified:
value = cls._value
cls._value <<= 1
else:
value = descriptor.value
cls._value = value << 1
return value
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6353793
constantly-23.10.4/constantly/_version.py 0000644 0000765 0000024 00000000763 14517313232 017530 0 ustar 00glyph staff
# This file was generated by 'versioneer.py' (0.29) from
# revision-control system data, or from the parent directory name of an
# unpacked source archive. Distribution tarballs contain a pre-generated copy
# of this file.
import json
version_json = '''
{
"date": "2023-10-28T16:14:45-0700",
"dirty": false,
"error": null,
"full-revisionid": "c63aa51794c314778b5699dd1cec9b3547fe6911",
"version": "23.10.4"
}
''' # END VERSION_JSON
def get_versions():
return json.loads(version_json)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6348457
constantly-23.10.4/constantly/test/ 0000755 0000765 0000024 00000000000 14517313232 016303 5 ustar 00glyph staff ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/constantly/test/__init__.py 0000644 0000765 0000024 00000000150 13641305077 020415 0 ustar 00glyph staff # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Tests for Constantly.
"""
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1585809983.0
constantly-23.10.4/constantly/test/test_constants.py 0000644 0000765 0000024 00000110764 13641305077 021746 0 ustar 00glyph staff # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Unit tests for L{constantly}.
"""
from __future__ import division, absolute_import
from twisted.trial.unittest import TestCase
from constantly import (
NamedConstant, Names, ValueConstant, Values, FlagConstant, Flags
)
class NamedConstantTests(TestCase):
"""
Tests for the L{constantly.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("", 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(object):
"""
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 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.assertIdentical(first, second)
class NamesTests(TestCase, _ConstantsTestsMixin):
"""
Tests for L{constantly.Names}, a base class for containers of
related constaints.
"""
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("", 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.assertIdentical(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.assertIdentical(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.assertIdentical(self.METHOD.GET, constants[0])
self.assertIdentical(self.METHOD.PUT, constants[1])
self.assertIdentical(self.METHOD.POST, constants[2])
self.assertIdentical(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.assertIdentical(again[0], constants[0])
self.assertIdentical(again[1], constants[1])
self.assertIdentical(again[2], constants[2])
self.assertIdentical(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(object):
something = self.METHOD.GET
self.assertIdentical(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(object):
something = self.METHOD.GET
self.assertIdentical(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 as the value of an attribute on "
"AnotherNames",
str(exc))
class ValuesTests(TestCase, _ConstantsTestsMixin):
"""
Tests for L{constantly.Names}, a base class for containers of
related constaints 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("", 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.assertIdentical(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.assertIdentical(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.assertIdentical(
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.assertIdentical(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.assertIdentical(self.STATUS.OK, constants[0])
self.assertIdentical(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.assertIdentical(again[0], constants[0])
self.assertIdentical(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(object):
"""
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{constantly.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("", 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.assertIdentical(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.assertIdentical(flag, self.FXF.READ)
flag = self.FXF.lookupByValue(0x02)
self.assertIdentical(flag, self.FXF.WRITE)
flag = self.FXF.lookupByValue(0x04)
self.assertIdentical(flag, self.FXF.APPEND)
flag = self.FXF.lookupByValue(0x20)
self.assertIdentical(flag, self.FXF.EXCLUSIVE)
flag = self.FXF.lookupByValue(0x40)
self.assertIdentical(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.assertIdentical(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.assertIdentical(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.assertIdentical(self.FXF.READ, constants[0])
self.assertIdentical(self.FXF.WRITE, constants[1])
self.assertIdentical(self.FXF.APPEND, constants[2])
self.assertIdentical(self.FXF.EXCLUSIVE, constants[3])
self.assertIdentical(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.assertIdentical(again[0], constants[0])
self.assertIdentical(again[1], constants[1])
self.assertIdentical(again[2], constants[2])
self.assertIdentical(again[3], constants[3])
self.assertIdentical(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("", 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), # No flags
set(()))
self.assertEqual(
set(self.FXF.WRITE),
set((self.FXF.WRITE,)))
self.assertEqual(
set(self.FXF.WRITE | self.FXF.EXCLUSIVE),
set((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("", 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("", 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("", 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{constantly.NamedConstant} preserves definition
order in C{<} comparisons.
"""
self.assertTrue(NamedLetters.alpha < NamedLetters.beta)
def test_orderedNameConstants_le(self):
"""
L{constantly.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{constantly.NamedConstant} preserves definition
order in C{>} comparisons.
"""
self.assertTrue(NamedLetters.beta > NamedLetters.alpha)
def test_orderedNameConstants_ge(self):
"""
L{constantly.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{constantly.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{constantly.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{constantly.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{constantly.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{constantly.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{constantly.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{constantly.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{constantly.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{constantly._constants._Constant.__lt__} returns C{NotImplemented}
when comparing constants of different types.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__lt__(ValuedLetters.alpha)
)
def test_orderedDifferentConstants_le(self):
"""
L{constantly._constants._Constant.__le__} returns C{NotImplemented}
when comparing constants of different types.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__le__(ValuedLetters.alpha)
)
def test_orderedDifferentConstants_gt(self):
"""
L{constantly._constants._Constant.__gt__} returns C{NotImplemented}
when comparing constants of different types.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__gt__(ValuedLetters.alpha)
)
def test_orderedDifferentConstants_ge(self):
"""
L{constantly._constants._Constant.__ge__} returns C{NotImplemented}
when comparing constants of different types.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__ge__(ValuedLetters.alpha)
)
def test_orderedDifferentContainers_lt(self):
"""
L{constantly._constants._Constant.__lt__} returns C{NotImplemented}
when comparing constants belonging to different containers.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__lt__(MoreNamedLetters.digamma)
)
def test_orderedDifferentContainers_le(self):
"""
L{constantly._constants._Constant.__le__} returns C{NotImplemented}
when comparing constants belonging to different containers.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__le__(MoreNamedLetters.digamma)
)
def test_orderedDifferentContainers_gt(self):
"""
L{constantly._constants._Constant.__gt__} returns C{NotImplemented}
when comparing constants belonging to different containers.
"""
self.assertEquals(
NotImplemented,
NamedLetters.alpha.__gt__(MoreNamedLetters.digamma)
)
def test_orderedDifferentContainers_ge(self):
"""
L{constantly._constants._Constant.__ge__} returns C{NotImplemented}
when comparing constants belonging to different containers.
"""
self.assertEquals(
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 cooresponding 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(u'\u0391')
digamma = ValueConstant(u'\u03dc')
zeta = ValueConstant(u'\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)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6346095
constantly-23.10.4/constantly.egg-info/ 0000755 0000765 0000024 00000000000 14517313232 017016 5 ustar 00glyph staff ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698535065.0
constantly-23.10.4/constantly.egg-info/PKG-INFO 0000644 0000765 0000024 00000003343 14517313231 020115 0 ustar 00glyph staff Metadata-Version: 2.1
Name: constantly
Version: 23.10.4
Summary: Symbolic constants in Python
Maintainer: Twisted Matrix Labs Developers
License: MIT
Project-URL: Homepage, https://github.com/twisted/constantly
Keywords: constants,enum,twisted
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
License-File: LICENSE
Constantly
==========
A library that provides symbolic constant support. It includes collections and
constants with text, numeric, and bit flag values. Originally
``twisted.python.constants`` from the `Twisted `_
project.
Installing
----------
constantly is available in `PyPI `_, and
can be installed via pip::
$ pip install constantly
Documentation
-------------------------
Documentation is available at ``_.
Tests
-----
To run tests::
$ tox
This will run tests on Python 2.7, 3.3, 3.4, and PyPy, as well as doing
coverage and pyflakes checks.
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698535065.0
constantly-23.10.4/constantly.egg-info/SOURCES.txt 0000644 0000765 0000024 00000000513 14517313231 020700 0 ustar 00glyph staff CREDITS
LICENSE
MANIFEST.in
README.rst
pyproject.toml
setup.py
constantly/__init__.py
constantly/_constants.py
constantly/_version.py
constantly.egg-info/PKG-INFO
constantly.egg-info/SOURCES.txt
constantly.egg-info/dependency_links.txt
constantly.egg-info/top_level.txt
constantly/test/__init__.py
constantly/test/test_constants.py ././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698535065.0
constantly-23.10.4/constantly.egg-info/dependency_links.txt 0000644 0000765 0000024 00000000001 14517313231 023063 0 ustar 00glyph staff
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698535065.0
constantly-23.10.4/constantly.egg-info/top_level.txt 0000644 0000765 0000024 00000000013 14517313231 021541 0 ustar 00glyph staff constantly
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698532976.0
constantly-23.10.4/pyproject.toml 0000644 0000765 0000024 00000002643 14517307160 016052 0 ustar 00glyph staff [build-system]
requires = ["setuptools>=68.2", "versioneer[toml]==0.29"]
build-backend = "setuptools.build_meta"
[project]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules",
]
description = "Symbolic constants in Python"
readme = "README.rst"
keywords = ["constants", "enum", "twisted"]
license = {text = "MIT"}
name = "constantly"
maintainers = [{name = "Twisted Matrix Labs Developers"}]
urls = {Homepage = "https://github.com/twisted/constantly"}
requires-python = ">= 3.8"
dynamic = ["version"]
[tool.setuptools]
include-package-data = false
[tool.setuptools.packages]
find = {namespaces = false}
[tool.versioneer]
VCS = "git"
style = "pep440"
versionfile_source = "constantly/_version.py"
versionfile_build = "constantly/_version.py"
tag_prefix = ""
parentdir_prefix = "constantly-"
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 010212 x ustar 00 28 mtime=1698535065.6352842
constantly-23.10.4/setup.cfg 0000644 0000765 0000024 00000000046 14517313232 014747 0 ustar 00glyph staff [egg_info]
tag_build =
tag_date = 0
././@PaxHeader 0000000 0000000 0000000 00000000026 00000000000 010213 x ustar 00 22 mtime=1698532976.0
constantly-23.10.4/setup.py 0000644 0000765 0000024 00000000321 14517307160 014637 0 ustar 00glyph staff # Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
import versioneer
from setuptools import setup
setup(
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
)