started work on backend
This commit is contained in:
@@ -0,0 +1,494 @@
|
||||
from __future__ import nested_scopes, generators, division, absolute_import, with_statement, \
|
||||
print_function, unicode_literals
|
||||
from . import compatibility
|
||||
|
||||
compatibility.backport() # noqa
|
||||
|
||||
import builtins
|
||||
|
||||
import os # noqa
|
||||
import sys # noqa
|
||||
|
||||
from io import UnsupportedOperation # noqa
|
||||
|
||||
|
||||
from collections import OrderedDict # noqa
|
||||
from unicodedata import normalize # noqa
|
||||
|
||||
import re # noqa
|
||||
import inspect # noqa
|
||||
from keyword import iskeyword # noqa
|
||||
|
||||
# region Compatibility Conditionals
|
||||
|
||||
# The following detects the presence of the typing library
|
||||
|
||||
try:
|
||||
from typing import Union, Optional, Iterable, Tuple, Any, Callable, AnyStr # noqa
|
||||
except ImportError:
|
||||
Union = Optional = Iterable = Tuple = Any = Callable = AnyStr = None
|
||||
|
||||
|
||||
# Before `collections.abc` existed, the definitions we use from this module were in `collections`
|
||||
try:
|
||||
import collections.abc as collections_abc
|
||||
import collections
|
||||
except ImportError:
|
||||
import collections
|
||||
collections_abc = collections
|
||||
|
||||
# Earlier versions of the `collections` library do not include the `Generator` class, so when this class is missing--
|
||||
# we employ a workaround.
|
||||
|
||||
if hasattr(collections_abc, 'Generator'):
|
||||
Generator = collections_abc.Generator
|
||||
else:
|
||||
Generator = type(n for n in (1, 2, 3))
|
||||
|
||||
# endregion
|
||||
|
||||
try:
|
||||
|
||||
from inspect import signature
|
||||
|
||||
getargspec = None
|
||||
|
||||
except ImportError:
|
||||
|
||||
signature = None
|
||||
|
||||
try:
|
||||
from inspect import getfullargspec
|
||||
except ImportError:
|
||||
from inspect import getargspec as getfullargspec
|
||||
|
||||
|
||||
_Module = type(re)
|
||||
|
||||
|
||||
def qualified_name(type_):
|
||||
# type: (Union[type, _Module]) -> str
|
||||
"""
|
||||
>>> print(qualified_name(qualified_name))
|
||||
qualified_name
|
||||
|
||||
>>> from serial import model
|
||||
>>> print(qualified_name(model.marshal))
|
||||
serial.model.marshal
|
||||
"""
|
||||
|
||||
if hasattr(type_, '__qualname__'):
|
||||
type_name = '.'.join(name_part for name_part in type_.__qualname__.split('.') if name_part[0] != '<')
|
||||
else:
|
||||
type_name = type_.__name__
|
||||
|
||||
if isinstance(type_, _Module):
|
||||
|
||||
if type_name in (
|
||||
'builtins', '__builtin__', '__main__', '__init__'
|
||||
):
|
||||
type_name = None
|
||||
|
||||
else:
|
||||
|
||||
if type_.__module__ not in (
|
||||
'builtins', '__builtin__', '__main__', '__init__'
|
||||
):
|
||||
type_name = type_.__module__ + '.' + type_name
|
||||
|
||||
return type_name
|
||||
|
||||
|
||||
def calling_function_qualified_name(depth=1):
|
||||
# type: (int) -> Optional[str]
|
||||
"""
|
||||
>>> def my_function(): return calling_function_qualified_name()
|
||||
>>> print(my_function())
|
||||
my_function
|
||||
"""
|
||||
|
||||
if not isinstance(depth, int):
|
||||
|
||||
depth_representation = repr(depth)
|
||||
|
||||
raise TypeError(
|
||||
'The parameter `depth` for `serial.utilities.calling_function_qualified_name` must be an `int`, not' +
|
||||
(
|
||||
(':\n%s' if '\n' in depth_representation else ' %s.') %
|
||||
depth_representation
|
||||
)
|
||||
)
|
||||
|
||||
stack = inspect.stack()
|
||||
|
||||
if len(stack) < (depth + 1):
|
||||
|
||||
return None
|
||||
|
||||
else:
|
||||
|
||||
name_list = []
|
||||
stack = inspect.stack()
|
||||
frame_info = stack[depth] # type: inspect.FrameInfo
|
||||
|
||||
try:
|
||||
frame_function = frame_info.function
|
||||
except AttributeError:
|
||||
frame_function = frame_info[3]
|
||||
|
||||
if frame_function != '<module>':
|
||||
|
||||
try:
|
||||
frame = frame_info.frame
|
||||
except AttributeError:
|
||||
frame = frame_info[0]
|
||||
|
||||
name_list.append(frame_function)
|
||||
arguments, _, _, frame_locals = inspect.getargvalues(frame)
|
||||
|
||||
if arguments:
|
||||
|
||||
argument = arguments[0]
|
||||
argument_value = frame_locals[argument]
|
||||
argument_value_type = type(argument_value)
|
||||
|
||||
if (
|
||||
hasattr(argument_value_type, '__name__') and
|
||||
hasattr(argument_value_type, '__module__') and
|
||||
(
|
||||
(argument_value_type.__name__ not in dir(builtins)) or
|
||||
(getattr(builtins, argument_value_type.__name__) is not argument_value_type)
|
||||
)
|
||||
):
|
||||
name_list.append(qualified_name(argument_value_type))
|
||||
|
||||
if len(name_list) < 2:
|
||||
|
||||
try:
|
||||
file_name = frame_info.filename
|
||||
except AttributeError:
|
||||
file_name = frame_info[1]
|
||||
|
||||
module_name = inspect.getmodulename(file_name)
|
||||
|
||||
if module_name not in sys.modules:
|
||||
|
||||
path_parts = list(os.path.split(file_name))
|
||||
path_parts.pop()
|
||||
|
||||
while path_parts:
|
||||
|
||||
parent = path_parts.pop()
|
||||
module_name = parent + '.' + module_name
|
||||
|
||||
if module_name in sys.modules:
|
||||
break
|
||||
|
||||
if module_name is None:
|
||||
raise ValueError('The path "%s" is not a python module' % file_name)
|
||||
else:
|
||||
if module_name in sys.modules:
|
||||
qualified_module_name = qualified_name(sys.modules[module_name])
|
||||
name_list.append(qualified_module_name)
|
||||
return '.'.join(reversed(name_list))
|
||||
|
||||
|
||||
def property_name(string):
|
||||
# type: (str) -> str
|
||||
"""
|
||||
Converts a "camelCased" attribute/property name, or a name which conflicts with a python keyword, to a
|
||||
pep8-compliant property name.
|
||||
|
||||
>>> print(property_name('theBirdsAndTheBees'))
|
||||
the_birds_and_the_bees
|
||||
|
||||
>>> print(property_name('FYIThisIsAnAcronym'))
|
||||
fyi_this_is_an_acronym
|
||||
|
||||
>>> print(property_name('in'))
|
||||
in_
|
||||
|
||||
>>> print(property_name('id'))
|
||||
id_
|
||||
"""
|
||||
pn = re.sub(
|
||||
r'__+',
|
||||
'_',
|
||||
re.sub(
|
||||
r'[^\w]+',
|
||||
'',
|
||||
re.sub(
|
||||
r'([a-zA-Z])([0-9])',
|
||||
r'\1_\2',
|
||||
re.sub(
|
||||
r'([0-9])([a-zA-Z])',
|
||||
r'\1_\2',
|
||||
re.sub(
|
||||
r'([A-Z])([A-Z])([a-z])',
|
||||
r'\1_\2\3',
|
||||
re.sub(
|
||||
r'([a-z])([A-Z])',
|
||||
r'\1_\2',
|
||||
re.sub(
|
||||
r'([^\x20-\x7F]|\s)+',
|
||||
'_',
|
||||
normalize('NFKD', string)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
).lower()
|
||||
if iskeyword(pn) or (pn in dir(builtins)):
|
||||
pn += '_'
|
||||
return pn
|
||||
|
||||
|
||||
def class_name(string):
|
||||
"""
|
||||
>>> print(class_name('the birds and the bees'))
|
||||
TheBirdsAndTheBees
|
||||
|
||||
>>> print(class_name('the-birds-and-the-bees'))
|
||||
TheBirdsAndTheBees
|
||||
|
||||
>>> print(class_name('**the - birds - and - the - bees**'))
|
||||
TheBirdsAndTheBees
|
||||
|
||||
>>> print(class_name('FYI is an acronym'))
|
||||
FYIIsAnAcronym
|
||||
|
||||
>>> print(class_name('in-you-go'))
|
||||
InYouGo
|
||||
|
||||
>>> print(class_name('False'))
|
||||
False_
|
||||
|
||||
>>> print(class_name('True'))
|
||||
True_
|
||||
|
||||
>>> print(class_name('ABC Acronym'))
|
||||
ABCAcronym
|
||||
"""
|
||||
return camel(string, capitalize=True)
|
||||
|
||||
|
||||
def camel(string, capitalize=False):
|
||||
# type: (str, bool) -> str
|
||||
"""
|
||||
>>> print(camel('the birds and the bees'))
|
||||
theBirdsAndTheBees
|
||||
|
||||
>>> print(camel('the-birds-and-the-bees'))
|
||||
theBirdsAndTheBees
|
||||
|
||||
>>> print(camel('**the - birds - and - the - bees**'))
|
||||
theBirdsAndTheBees
|
||||
|
||||
>>> print(camel('FYI is an acronym'))
|
||||
fyiIsAnAcronym
|
||||
|
||||
>>> print(camel('in-you-go'))
|
||||
inYouGo
|
||||
|
||||
>>> print(camel('False'))
|
||||
false
|
||||
|
||||
>>> print(camel('True'))
|
||||
true
|
||||
|
||||
>>> print(camel('in'))
|
||||
in_
|
||||
"""
|
||||
string = normalize('NFKD', string)
|
||||
characters = []
|
||||
if not capitalize:
|
||||
string = string.lower()
|
||||
capitalize_next = capitalize
|
||||
for s in string:
|
||||
if s in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789':
|
||||
if capitalize_next:
|
||||
if capitalize or characters:
|
||||
s = s.upper()
|
||||
characters.append(s)
|
||||
capitalize_next = False
|
||||
else:
|
||||
capitalize_next = True
|
||||
cn = ''.join(characters)
|
||||
if iskeyword(cn) or (cn in dir(builtins)):
|
||||
cn += '_'
|
||||
return cn
|
||||
|
||||
|
||||
def get_source(o):
|
||||
# type: (object) -> str
|
||||
if hasattr(o, '_source') and isinstance(o._source, str):
|
||||
result = o._source
|
||||
else:
|
||||
result = inspect.getsource(o)
|
||||
return result
|
||||
|
||||
|
||||
def camel_split(string):
|
||||
# test: (str) -> str
|
||||
"""
|
||||
>>> print('(%s)' % ', '.join("'%s'" % s for s in camel_split('theBirdsAndTheBees')))
|
||||
('the', 'Birds', 'And', 'The', 'Bees')
|
||||
>>> print('(%s)' % ', '.join("'%s'" % s for s in camel_split('theBirdsAndTheBees123')))
|
||||
('the', 'Birds', 'And', 'The', 'Bees', '123')
|
||||
>>> print('(%s)' % ', '.join("'%s'" % s for s in camel_split('theBirdsAndTheBeesABC123')))
|
||||
('the', 'Birds', 'And', 'The', 'Bees', 'ABC', '123')
|
||||
>>> print('(%s)' % ', '.join("'%s'" % s for s in camel_split('the-Birds-And-The-Bees-ABC--123')))
|
||||
('the', '-', 'Birds', '-', 'And', '-', 'The', '-', 'Bees', '-', 'ABC', '--', '123')
|
||||
>>> print('(%s)' % ', '.join("'%s'" % s for s in camel_split('THEBirdsAndTheBees')))
|
||||
('THE', 'Birds', 'And', 'The', 'Bees')
|
||||
"""
|
||||
words = []
|
||||
character_type = None
|
||||
acronym = False
|
||||
for s in string:
|
||||
if s in '0123456789':
|
||||
if character_type == 0:
|
||||
words[-1].append(s)
|
||||
else:
|
||||
words.append([s])
|
||||
character_type = 0
|
||||
acronym = False
|
||||
elif s in 'abcdefghijklmnopqrstuvwxyz':
|
||||
if character_type == 1:
|
||||
words[-1].append(s)
|
||||
elif character_type == 2:
|
||||
if acronym:
|
||||
words.append([words[-1].pop()] + [s])
|
||||
else:
|
||||
words[-1].append(s)
|
||||
else:
|
||||
words.append([s])
|
||||
character_type = 1
|
||||
acronym = False
|
||||
elif s in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
|
||||
if character_type == 2:
|
||||
words[-1].append(s)
|
||||
acronym = True
|
||||
else:
|
||||
words.append([s])
|
||||
acronym = False
|
||||
character_type = 2
|
||||
else:
|
||||
if character_type == 3:
|
||||
words[-1].append(s)
|
||||
else:
|
||||
words.append([s])
|
||||
character_type = 3
|
||||
return tuple(
|
||||
''.join(w) for w in words
|
||||
)
|
||||
|
||||
|
||||
def properties_values(o):
|
||||
# type: (object) -> Sequence[Tuple[AnyStr, Any]]
|
||||
for a in dir(o):
|
||||
if a[0] != '_':
|
||||
v = getattr(o, a)
|
||||
if not callable(v):
|
||||
yield a, v
|
||||
|
||||
|
||||
UNDEFINED = None
|
||||
|
||||
|
||||
class Undefined(object):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
if UNDEFINED is not None:
|
||||
raise RuntimeError(
|
||||
'%s may only be defined once.' % repr(self)
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
'UNDEFINED'
|
||||
if self.__module__ in ('__main__', 'builtins', '__builtin__', __name__) else
|
||||
'%s.UNDEFINED' % self.__module__
|
||||
)
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
def __hash__(self):
|
||||
return 0
|
||||
|
||||
def __eq__(self, other):
|
||||
# type: (Any) -> bool
|
||||
return other is self
|
||||
|
||||
|
||||
UNDEFINED = Undefined()
|
||||
|
||||
|
||||
def parameters_defaults(function):
|
||||
# type: (Callable) -> OrderedDict
|
||||
"""
|
||||
Returns an ordered dictionary mapping a function's argument names to default values, or `UNDEFINED` in the case of
|
||||
positional arguments.
|
||||
|
||||
>>> class X(object):
|
||||
...
|
||||
... def __init__(self, a, b, c, d=1, e=2, f=3):
|
||||
... pass
|
||||
...
|
||||
>>> print(list(parameters_defaults(X.__init__).items()))
|
||||
[('self', UNDEFINED), ('a', UNDEFINED), ('b', UNDEFINED), ('c', UNDEFINED), ('d', 1), ('e', 2), ('f', 3)]
|
||||
"""
|
||||
pd = OrderedDict()
|
||||
if signature is None:
|
||||
spec = getfullargspec(function)
|
||||
i = - 1
|
||||
for a in spec.args:
|
||||
pd[a] = UNDEFINED
|
||||
for a in reversed(spec.args):
|
||||
try:
|
||||
pd[a] = spec.defaults[i]
|
||||
except IndexError:
|
||||
break
|
||||
i -= 1
|
||||
else:
|
||||
for pn, p in signature(function).parameters.items():
|
||||
if p.default is inspect.Parameter.empty:
|
||||
pd[pn] = UNDEFINED
|
||||
else:
|
||||
pd[pn] = p.default
|
||||
return pd
|
||||
|
||||
|
||||
def read(data):
|
||||
# type: (Union[str, IOBase, addbase]) -> Any
|
||||
if (
|
||||
(hasattr(data, 'readall') and callable(data.readall)) or
|
||||
(hasattr(data, 'read') and callable(data.read))
|
||||
):
|
||||
if hasattr(data, 'seek') and callable(data.seek):
|
||||
try:
|
||||
data.seek(0)
|
||||
except UnsupportedOperation:
|
||||
pass
|
||||
if hasattr(data, 'readall') and callable(data.readall):
|
||||
try:
|
||||
data = data.readall()
|
||||
except UnsupportedOperation:
|
||||
data = data.read()
|
||||
else:
|
||||
data = data.read()
|
||||
return data
|
||||
else:
|
||||
raise TypeError(
|
||||
'%s is not a file-like object' % repr(data)
|
||||
)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
from __future__ import nested_scopes, generators, division, absolute_import, with_statement, \
|
||||
print_function, unicode_literals
|
||||
import inspect
|
||||
|
||||
BACKWARDS_COMPATIBILITY_IMPORTS = '\n'.join(
|
||||
(
|
||||
'# region Backwards Compatibility',
|
||||
'from __future__ import nested_scopes, generators, division, absolute_import, with_statement, \\',
|
||||
' print_function, unicode_literals',
|
||||
'from future import standard_library',
|
||||
'standard_library.install_aliases()',
|
||||
'from future.builtins import *',
|
||||
'# endregion'
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def backport():
|
||||
# type: (...) -> None
|
||||
|
||||
frame_info = inspect.stack()[1] # type: inspect.FrameInfo
|
||||
|
||||
try:
|
||||
frame = frame_info.frame
|
||||
except AttributeError:
|
||||
frame = frame_info[0]
|
||||
|
||||
exec(BACKWARDS_COMPATIBILITY_IMPORTS, frame.f_globals, frame.f_locals)
|
||||
|
||||
Reference in New Issue
Block a user