Source code for spyder.api.utils
# -*- coding: utf-8 -*-
#
# Copyright (c) 2009- Spyder Project Contributors
#
# Distributed under the terms of the MIT License
# (see spyder/__init__.py for details)
"""
API utilities.
"""
from abc import ABCMeta as BaseABCMeta
import sys
import typing
if sys.version_info < (3, 10):
from typing_extensions import ParamSpec
else:
from typing import ParamSpec # noqa: ICN003
_P = ParamSpec('_P')
_T = typing.TypeVar('_T')
[docs]
def get_class_values(cls):
"""
Get the attribute values for the class enumerations used in our API.
Idea from: https://stackoverflow.com/a/17249228/438386
"""
return [v for (k, v) in cls.__dict__.items() if k[:1] != '_']
[docs]
class PrefixNode:
"""Utility class used to represent a prefixed string tuple."""
def __init__(self, path=None):
self.children = {}
self.path = path
def __iter__(self):
prefix = [((self.path,), self)]
while prefix != []:
current_prefix, node = prefix.pop(0)
prefix += [(current_prefix + (c,), node.children[c])
for c in node.children]
yield current_prefix
def add_path(self, path):
prefix, *rest = path
if prefix not in self.children:
self.children[prefix] = PrefixNode(prefix)
if len(rest) > 0:
child = self.children[prefix]
child.add_path(rest)
[docs]
class PrefixedTuple(PrefixNode):
"""Utility class to store and iterate over prefixed string tuples."""
def __iter__(self):
for key in self.children:
child = self.children[key]
for prefix in child:
yield prefix
[docs]
class classproperty(property):
"""
Decorator to declare class constants as properties that require additional
computation.
Taken from: https://stackoverflow.com/a/7864317/438386
"""
def __get__(self, cls, owner):
return classmethod(self.fget).__get__(None, owner)()
[docs]
class DummyAttribute:
"""
Dummy class to mark abstract attributes.
"""
pass
[docs]
def abstract_attribute(
obj: typing.Optional[
typing.Union[typing.Callable[_P, _T], DummyAttribute]
] = None
) -> _T:
"""
Decorator to mark abstract attributes. Must be used in conjunction with the
ABCMeta metaclass.
"""
if obj is None:
obj = DummyAttribute()
setattr(obj, "__is_abstract_attribute__", True)
return obj # type: ignore