diff options
| author | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
|---|---|---|
| committer | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
| commit | 4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch) | |
| tree | ee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/strenum | |
| parent | cc961e04ba734dd72309fb548a2f97d67d578813 (diff) | |
| download | gn-ai-master.tar.gz | |
Diffstat (limited to '.venv/lib/python3.12/site-packages/strenum')
8 files changed, 605 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/strenum/__init__.py b/.venv/lib/python3.12/site-packages/strenum/__init__.py new file mode 100644 index 00000000..1c82bede --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/__init__.py @@ -0,0 +1,325 @@ +import enum +from ._version import get_versions +from ._name_mangler import _NameMangler + +__version__ = get_versions()["version"] +__version_info__ = tuple(int(n) for n in __version__.partition("+")[0].split(".")) +del get_versions + +_name_mangler = _NameMangler() + +# The first argument to the `_generate_next_value_` function of the `enum.Enum` +# class is documented to be the name of the enum member, not the enum class: +# +# https://docs.python.org/3.6/library/enum.html#using-automatic-values +# +# Pylint, though, doesn't know about this so we need to disable it's check for +# `self` arguments. +# pylint: disable=no-self-argument + + +class StrEnum(str, enum.Enum): + """ + StrEnum is a Python ``enum.Enum`` that inherits from ``str``. The default + ``auto()`` behavior uses the member name as its value. + + Example usage:: + + class Example(StrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER_CASE" + assert Example.lower_case == "lower_case" + assert Example.MixedCase == "MixedCase" + """ + + def __new__(cls, value, *args, **kwargs): + if not isinstance(value, (str, enum.auto)): + raise TypeError( + f"Values of StrEnums must be strings: {value!r} is a {type(value)}" + ) + return super().__new__(cls, value, *args, **kwargs) + + def __str__(self): + return str(self.value) + + def _generate_next_value_(name, *_): + return name + + +class LowercaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `lowercase` to + produce each member's value. + + Example usage:: + + class Example(LowercaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "upper_case" + assert Example.lower_case == "lower_case" + assert Example.MixedCase == "mixedcase" + + .. versionadded:: 0.4.3 + """ + + def _generate_next_value_(name, *_): + return name.lower() + + +class UppercaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `UPPERCASE` to + produce each member's value. + + Example usage:: + + class Example(UppercaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER_CASE" + assert Example.lower_case == "LOWER_CASE" + assert Example.MixedCase == "MIXEDCASE" + + .. versionadded:: 0.4.3 + """ + + def _generate_next_value_(name, *_): + return name.upper() + + +class CamelCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `camelCase` to + produce each member's value. + + Example usage:: + + class Example(CamelCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "upperCase" + assert Example.lower_case == "lowerCase" + assert Example.MixedCase == "mixedCase" + + .. versionadded:: 0.4.5 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.camel(name) + + +class PascalCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `PascalCase` to + produce each member's value. + + Example usage:: + + class Example(PascalCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UpperCase" + assert Example.lower_case == "LowerCase" + assert Example.MixedCase == "MixedCase" + + .. versionadded:: 0.4.5 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.pascal(name) + + +class KebabCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `kebab-case` to + produce each member's value. + + Example usage:: + + class Example(KebabCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "upper-case" + assert Example.lower_case == "lower-case" + assert Example.MixedCase == "mixed-case" + + .. versionadded:: 0.4.5 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.kebab(name) + + +class SnakeCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `snake_case` to + produce each member's value. + + Example usage:: + + class Example(SnakeCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "upper_case" + assert Example.lower_case == "lower_case" + assert Example.MixedCase == "mixed_case" + + .. versionadded:: 0.4.5 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.snake(name) + + +class MacroCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `MACRO_CASE` to + produce each member's value. + + Example usage:: + + class Example(MacroCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER_CASE" + assert Example.lower_case == "LOWER_CASE" + assert Example.MixedCase == "MIXED_CASE" + + .. versionadded:: 0.4.6 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.macro(name) + + +class CamelSnakeCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `camel_Snake_Case` to + produce each member's value. + + Example usage:: + + class Example(CamelSnakeCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "upper_Case" + assert Example.lower_case == "lower_Case" + assert Example.MixedCase == "mixed_Case" + + .. versionadded:: 0.4.8 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.camel_snake(name) + + +class PascalSnakeCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `Pascal_Snake_Case` to + produce each member's value. + + Example usage:: + + class Example(PascalSnakeCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "Upper_Case" + assert Example.lower_case == "Lower_Case" + assert Example.MixedCase == "Mixed_Case" + + .. versionadded:: 0.4.8 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.pascal_snake(name) + + +class SpongebobCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `SpONGEBob_CAse` to + produce each member's value. + + Example usage:: + + class Example(SpongebobCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "uPpER_cAsE" + assert Example.lower_case == "lowER_CASe" + assert Example.MixedCase == "MixeD_CAse" + + .. versionadded:: 0.4.8 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.spongebob(name) + + +class CobolCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `COBOL-CASE` to + produce each member's value. + + Example usage:: + + class Example(CobolCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "UPPER-CASE" + assert Example.lower_case == "LOWER-CASE" + assert Example.MixedCase == "MIXED-CASE" + + .. versionadded:: 0.4.8 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.cobol(name) + + +class HttpHeaderCaseStrEnum(StrEnum): + """ + A ``StrEnum`` where ``auto()`` will convert the name to `Http-Header-Case` to + produce each member's value. + + Example usage:: + + class Example(HttpHeaderCaseStrEnum): + UPPER_CASE = auto() + lower_case = auto() + MixedCase = auto() + + assert Example.UPPER_CASE == "Upper-Case" + assert Example.lower_case == "Lower-Case" + assert Example.MixedCase == "Mixed-Case" + + .. versionadded:: 0.4.8 + """ + + def _generate_next_value_(name, *_): + return _name_mangler.http_header(name) diff --git a/.venv/lib/python3.12/site-packages/strenum/__init__.pyi b/.venv/lib/python3.12/site-packages/strenum/__init__.pyi new file mode 100644 index 00000000..3ad1a910 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/__init__.pyi @@ -0,0 +1,43 @@ +import enum +from typing import Union, Sequence, Mapping, Any + +class StrEnum(str, enum.Enum): + def __new__(cls, value: Union[str, enum.auto], *args: Sequence[Any], **kwargs: Mapping[Any, Any]) -> StrEnum: ... + def __str__(self) -> str: ... + def _generate_next_value_(name: str, *_) -> str: ... + +class LowercaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class UppercaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class CamelCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class PascalCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class KebabCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class SnakeCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class MacroCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class CamelSnakeCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class PascalSnakeCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class SpongebobCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class CobolCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... + +class HttpHeaderCaseStrEnum(StrEnum): + def _generate_next_value_(name: str, *_) -> str: ... diff --git a/.venv/lib/python3.12/site-packages/strenum/_name_mangler.py b/.venv/lib/python3.12/site-packages/strenum/_name_mangler.py new file mode 100644 index 00000000..8906e594 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/_name_mangler.py @@ -0,0 +1,127 @@ +# pylint: disable=no-name-in-module +import re +from zlib import crc32 + + +class _NameMangler: + _regex = re.compile(r"([A-Z]?[a-z]+)|([A-Z]+(?![a-z]))") + + def words(self, name): + """ + Split a string into words. Should correctly handle splitting: + camelCase + PascalCase + kebab-case + snake_case + MACRO_CASE + camel_Snake_Case + Pascal_Snake_Case + COBOL-CASE + Http-Header-Case + + It _does not_ handle splitting spongebob case. + """ + yield from (m.group(0) for m in self._regex.finditer(name)) + + def camel(self, name): + """ + Convert a name to camelCase + """ + + def cased_words(word_iter): + yield next(word_iter, "").lower() + yield from (w.title() for w in word_iter) + + return "".join(cased_words(self.words(name))) + + def pascal(self, name): + """ + Convert a name to PascalCase + """ + + return "".join(w.title() for w in self.words(name)) + + def kebab(self, name): + """ + Convert a name to kebab-case + """ + + return "-".join(w.lower() for w in self.words(name)) + + def snake(self, name): + """ + Convert a name to snake_case + """ + + return "_".join(w.lower() for w in self.words(name)) + + def macro(self, name): + """ + Convert a name to MACRO_CASE + """ + + return "_".join(w.upper() for w in self.words(name)) + + # The following are inspired by examples in the Wikipedia + # [Naming convention](https://en.wikipedia.org/wiki/Naming_convention_(programming)) + # article + + def camel_snake(self, name): + """ + Convert a name to camel_Snake_Case + """ + + def cased_words(word_iter): + yield next(word_iter, "").lower() + yield from (w.title() for w in word_iter) + + return "_".join(cased_words(self.words(name))) + + def pascal_snake(self, name): + """ + Convert a name to Pascal_Snake_Case + """ + + return "_".join(w.title() for w in self.words(name)) + + def spongebob(self, name): + """ + Convert a name to SpOngEBOb_CASe + + The PRNG we use is seeded with the word to be scrambled. This produces + stable output so the same input will always produce in the same output. + It's not `truly` random, but your tests will thank me. + """ + + def prng(seed_word): + state = 1 << 31 | crc32(seed_word.encode("utf-8")) | 1 + + def step(state): + state = state >> 1 | (state & 0x01 ^ ((state & 0x02) >> 1)) << 31 + bit = state & 0x1 + return bit, state + + for _ in range(100): + _, state = step(state) + while True: + bit, state = step(state) + yield str.upper if bit else str.lower + + def scramble(word): + return "".join(f(ch) for ch, f in zip(word, prng(word))) + + return "_".join(scramble(w) for w in self.words(name)) + + def cobol(self, name): + """ + Convert a name to COBOL-CASE + """ + + return "-".join(w.upper() for w in self.words(name)) + + def http_header(self, name): + """ + Convert a name to Http-Header-Case + """ + + return "-".join(w.title() for w in self.words(name)) diff --git a/.venv/lib/python3.12/site-packages/strenum/_name_mangler.pyi b/.venv/lib/python3.12/site-packages/strenum/_name_mangler.pyi new file mode 100644 index 00000000..65fe6557 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/_name_mangler.pyi @@ -0,0 +1,15 @@ +import re +from zlib import crc32 + +class _NameMangler: + def words(self, name: str) -> str: ... + def camel(self, name: str) -> str: ... + def pascal(self, name: str) -> str: ... + def kebab(self, name: str) -> str: ... + def snake(self, name: str) -> str: ... + def macro(self, name: str) -> str: ... + def camel_snake(self, name: str) -> str: ... + def pascal_snake(self, name: str) -> str: ... + def spongebob(self, name: str) -> str: ... + def cobol(self, name: str) -> str: ... + def http_header(self, name: str) -> str: ... diff --git a/.venv/lib/python3.12/site-packages/strenum/_version.py b/.venv/lib/python3.12/site-packages/strenum/_version.py new file mode 100644 index 00000000..864eeb31 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/_version.py @@ -0,0 +1,21 @@ + +# This file was generated by 'versioneer.py' (0.18) 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-06-29T23:39:30+0200", + "dirty": false, + "error": null, + "full-revisionid": "ab34b770aacac80431cd77f28770a60144679d38", + "version": "0.4.15" +} +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) diff --git a/.venv/lib/python3.12/site-packages/strenum/mixins.py b/.venv/lib/python3.12/site-packages/strenum/mixins.py new file mode 100644 index 00000000..3e5c7e49 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/mixins.py @@ -0,0 +1,64 @@ +class Comparable: + """Customise how your Enum acts when compared to other objects. + + Your Enum must implement a ``_cmp_values`` method which takes the Enum + member's value and the other value and manipulates them into the actual + values that can be compared. + + A case-insensitive StrEnum might look like this:: + + class HttpHeader(Comparable, KebabCaseStrEnum): + ContentType = auto() + Host = auto() + Accept = auto() + XForwardedFor = auto() + + def _cmp_values(self, other): + return self.value.lower(), str(other).lower() + + You could then use these headers in case-insensitive comparisons:: + + assert "Content-Type" == HttpHeader.ContentType + assert "content-type" == HttpHeader.ContentType + assert "coNtEnt-tyPe" == HttpHeader.ContentType + + .. note:: + Your ``_cmp_values`` method *must not* return ``self`` as one of the + values to be compared -- that would result in infinite recursion. + Instead, perform operations on ``self.value`` and return that. + + .. warning:: + A bug in Python prior to 3.7.1 prevents mix-ins working with Enum + subclasses. + + .. versionadded:: 0.4.6 + """ + + def __eq__(self, other): + value, other = self._cmp_values(other) + return value == other + + def __ne__(self, other): + value, other = self._cmp_values(other) + return value != other + + def __lt__(self, other): + value, other = self._cmp_values(other) + return value < other + + def __le__(self, other): + value, other = self._cmp_values(other) + return value <= other + + def __gt__(self, other): + value, other = self._cmp_values(other) + return value > other + + def __ge__(self, other): + value, other = self._cmp_values(other) + return value >= other + + def _cmp_values(self, other): + raise NotImplementedError( + "Enum's using Comparable must implement their own _cmp_values function." + ) diff --git a/.venv/lib/python3.12/site-packages/strenum/mixins.pyi b/.venv/lib/python3.12/site-packages/strenum/mixins.pyi new file mode 100644 index 00000000..0cfac777 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/mixins.pyi @@ -0,0 +1,10 @@ +from typing import Tuple, Any + +class Comparable: + def __eq__(self, other: Any) -> bool: ... + def __ne__(self, other: Any) -> bool: ... + def __lt__(self, other: Any) -> bool: ... + def __le__(self, other: Any) -> bool: ... + def __gt__(self, other: Any) -> bool: ... + def __ge__(self, other: Any) -> bool: ... + def _cmp_values(self, other: Any) -> Tuple[str, str]: ... diff --git a/.venv/lib/python3.12/site-packages/strenum/py.typed b/.venv/lib/python3.12/site-packages/strenum/py.typed new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/strenum/py.typed |
