|
4 | 4 | from traitlets import ClassBasedTraitType
|
5 | 5 | from traitlets import TraitError
|
6 | 6 | from traitlets import Undefined
|
7 |
| - |
8 |
| -# Traitlet's 5.x includes a set of utilities for building |
9 |
| -# description strings for objects. Traitlets 5.x does not |
10 |
| -# support Python 3.6, but jupyter_server does; instead |
11 |
| -# jupyter_server uses traitlets 4.3.x which doesn't have |
12 |
| -# this `descriptions` submodule. This chunk in the except |
13 |
| -# clause is a copy-and-paste from traitlets 5.0.5. |
14 |
| -try: |
15 |
| - from traitlets.utils.descriptions import describe |
16 |
| -except ImportError: |
17 |
| - import re |
18 |
| - import types |
19 |
| - |
20 |
| - def describe(article, value, name=None, verbose=False, capital=False): |
21 |
| - """Return string that describes a value |
22 |
| - Parameters |
23 |
| - ---------- |
24 |
| - article : str or None |
25 |
| - A definite or indefinite article. If the article is |
26 |
| - indefinite (i.e. "a" or "an") the appropriate one |
27 |
| - will be infered. Thus, the arguments of ``describe`` |
28 |
| - can themselves represent what the resulting string |
29 |
| - will actually look like. If None, then no article |
30 |
| - will be prepended to the result. For non-articled |
31 |
| - description, values that are instances are treated |
32 |
| - definitely, while classes are handled indefinitely. |
33 |
| - value : any |
34 |
| - The value which will be named. |
35 |
| - name : str or None (default: None) |
36 |
| - Only applies when ``article`` is "the" - this |
37 |
| - ``name`` is a definite reference to the value. |
38 |
| - By default one will be infered from the value's |
39 |
| - type and repr methods. |
40 |
| - verbose : bool (default: False) |
41 |
| - Whether the name should be concise or verbose. When |
42 |
| - possible, verbose names include the module, and/or |
43 |
| - class name where an object was defined. |
44 |
| - capital : bool (default: False) |
45 |
| - Whether the first letter of the article should |
46 |
| - be capitalized or not. By default it is not. |
47 |
| - Examples |
48 |
| - -------- |
49 |
| - Indefinite description: |
50 |
| - >>> describe("a", object()) |
51 |
| - 'an object' |
52 |
| - >>> describe("a", object) |
53 |
| - 'an object' |
54 |
| - >>> describe("a", type(object)) |
55 |
| - 'a type' |
56 |
| -
|
57 |
| - Definite description: |
58 |
| - >>> describe("the", object()) # doctest: +ELLIPSIS |
59 |
| - "the object at '0x...'" |
60 |
| - >>> describe("the", object) |
61 |
| - 'the object object' |
62 |
| - >>> describe("the", type(object)) |
63 |
| - 'the type type' |
64 |
| -
|
65 |
| - Definitely named description: |
66 |
| - >>> describe("the", object(), "I made") |
67 |
| - 'the object I made' |
68 |
| - >>> describe("the", object, "I will use") |
69 |
| - 'the object I will use' |
70 |
| - """ |
71 |
| - if isinstance(article, str): |
72 |
| - article = article.lower() |
73 |
| - |
74 |
| - if not inspect.isclass(value): |
75 |
| - typename = type(value).__name__ |
76 |
| - else: |
77 |
| - typename = value.__name__ |
78 |
| - if verbose: |
79 |
| - typename = _prefix(value) + typename |
80 |
| - |
81 |
| - if article == "the" or (article is None and not inspect.isclass(value)): |
82 |
| - if name is not None: |
83 |
| - result = "{} {}".format(typename, name) |
84 |
| - if article is not None: |
85 |
| - return add_article(result, True, capital) |
86 |
| - else: |
87 |
| - return result |
88 |
| - else: |
89 |
| - tick_wrap = False |
90 |
| - if inspect.isclass(value): |
91 |
| - name = value.__name__ |
92 |
| - elif isinstance(value, types.FunctionType): |
93 |
| - name = value.__name__ |
94 |
| - tick_wrap = True |
95 |
| - elif isinstance(value, types.MethodType): |
96 |
| - name = value.__func__.__name__ |
97 |
| - tick_wrap = True |
98 |
| - elif type(value).__repr__ in (object.__repr__, type.__repr__): |
99 |
| - name = "at '%s'" % hex(id(value)) |
100 |
| - verbose = False |
101 |
| - else: |
102 |
| - name = repr(value) |
103 |
| - verbose = False |
104 |
| - if verbose: |
105 |
| - name = _prefix(value) + name |
106 |
| - if tick_wrap: |
107 |
| - name = name.join("''") |
108 |
| - return describe(article, value, name=name, verbose=verbose, capital=capital) |
109 |
| - elif article in ("a", "an") or article is None: |
110 |
| - if article is None: |
111 |
| - return typename |
112 |
| - return add_article(typename, False, capital) |
113 |
| - else: |
114 |
| - raise ValueError( |
115 |
| - "The 'article' argument should " "be 'the', 'a', 'an', or None not %r" % article |
116 |
| - ) |
117 |
| - |
118 |
| - def add_article(name, definite=False, capital=False): |
119 |
| - """Returns the string with a prepended article. |
120 |
| - The input does not need to begin with a charater. |
121 |
| - Parameters |
122 |
| - ---------- |
123 |
| - definite : bool (default: False) |
124 |
| - Whether the article is definite or not. |
125 |
| - Indefinite articles being 'a' and 'an', |
126 |
| - while 'the' is definite. |
127 |
| - capital : bool (default: False) |
128 |
| - Whether the added article should have |
129 |
| - its first letter capitalized or not. |
130 |
| - """ |
131 |
| - if definite: |
132 |
| - result = "the " + name |
133 |
| - else: |
134 |
| - first_letters = re.compile(r"[\W_]+").sub("", name) |
135 |
| - if first_letters[:1].lower() in "aeiou": |
136 |
| - result = "an " + name |
137 |
| - else: |
138 |
| - result = "a " + name |
139 |
| - if capital: |
140 |
| - return result[0].upper() + result[1:] |
141 |
| - else: |
142 |
| - return result |
143 |
| - |
144 |
| - def _prefix(value): |
145 |
| - if isinstance(value, types.MethodType): |
146 |
| - name = describe(None, value.__self__, verbose=True) + "." |
147 |
| - else: |
148 |
| - module = inspect.getmodule(value) |
149 |
| - if module is not None and module.__name__ != "builtins": |
150 |
| - name = module.__name__ + "." |
151 |
| - else: |
152 |
| - name = "" |
153 |
| - return name |
| 7 | +from traitlets.utils.descriptions import describe |
154 | 8 |
|
155 | 9 |
|
156 | 10 | class TypeFromClasses(ClassBasedTraitType):
|
|
0 commit comments