1#cython: embedsignature=True, annotation_typing=False
2
3import sys
4
5if sys.version_info >= (3, 4):
6    def funcdoc(f):
7        if not f.__text_signature__:
8            return f.__doc__
9        doc = '%s%s' % (f.__name__, f.__text_signature__)
10        if f.__doc__:
11            if '\n' in f.__doc__:
12                # preceding line endings get stripped
13                doc = '%s\n\n%s' % (doc, f.__doc__)
14            else:
15                doc = '%s\n%s' % (doc, f.__doc__)
16        return doc
17
18else:
19    def funcdoc(f):
20        return f.__doc__
21
22
23# note the r, we use \n below
24__doc__ = ur"""
25    >>> print (Ext.__doc__)
26    Ext(a, b, c=None)
27
28    >>> print (Ext.attr0.__doc__)
29    attr0: 'int'
30    attr0 docstring
31    >>> print (Ext.attr1.__doc__)
32    attr1: object
33    attr1 docstring
34    >>> print (Ext.attr2.__doc__)
35    attr2: list
36    >>> print (Ext.attr3.__doc__)
37    attr3: embedsignatures.Ext
38
39    >>> print (Ext.prop0.__doc__)
40    prop0 docstring
41    >>> print (Ext.prop1.__doc__)
42    None
43    >>> print (Ext.attr4.__doc__)
44    attr4 docstring
45    >>> print (Ext.attr5.__doc__)
46    attr5: 'int'
47    attr5 docstring
48
49    >>> print (Ext.a.__doc__)
50    Ext.a(self)
51
52    >>> print (Ext.b.__doc__)
53    Ext.b(self, a, b, c)
54
55    >>> print (Ext.c.__doc__)
56    Ext.c(self, a, b, c=1)
57
58    >>> print (Ext.d.__doc__)
59    Ext.d(self, a, b, *, c=88)
60
61    >>> print (Ext.e.__doc__)
62    Ext.e(self, a, b, c=88, **kwds)
63
64    >>> print (Ext.f.__doc__)
65    Ext.f(self, a, b, *, c, d=42)
66
67    >>> print (Ext.g.__doc__)
68    Ext.g(self, a, b, *, c, d=42, e=17, f, **kwds)
69
70    >>> print (Ext.h.__doc__)
71    Ext.h(self, a, b, *args, c, d=42, e=17, f, **kwds)
72
73    >>> print (Ext.k.__doc__)
74    Ext.k(self, a, b, c=1, *args, d=42, e=17, f, **kwds)
75
76    >>> print (Ext.l.__doc__)
77    Ext.l(self, a, b, c=1, *args, d=42, e=17, f, **kwds)
78    Existing string
79
80    >>> print (Ext.m.__doc__)
81    Ext.m(self, a=u'spam')
82
83    >>> print (Ext.n.__doc__)
84    Ext.n(self, a: int, b: float = 1.0, *args: tuple, **kwargs: dict) -> (None, True)
85
86    >>> print (Ext.get_int.__doc__)
87    Ext.get_int(self) -> int
88
89    >>> print (Ext.get_float.__doc__)
90    Ext.get_float(self) -> float
91
92    >>> print (Ext.get_str.__doc__)
93    Ext.get_str(self) -> str
94    Existing string
95
96    >>> print (Ext.clone.__doc__)
97    Ext.clone(self) -> Ext
98
99    >>> print (funcdoc(foo))
100    foo()
101
102    >>> funcdoc(with_doc_1)
103    'with_doc_1(a, b, c)\nExisting string'
104
105    >>> funcdoc(with_doc_2)
106    'with_doc_2(a, b, c)\n\n    Existing string\n    '
107
108    >>> funcdoc(with_doc_3)
109    'with_doc_3(a, b, c)\nExisting string'
110
111    >>> funcdoc(with_doc_4)
112    'with_doc_4(int a, str b, list c) -> str\n\n    Existing string\n    '
113
114    >>> funcdoc(f_sd)
115    "f_sd(str s='spam')"
116
117    >>> funcdoc(cf_sd)
118    "cf_sd(str s='spam') -> str"
119
120    >>> funcdoc(types)
121    'types(Ext a, int b, unsigned short c, float d, e)'
122
123    >>> print(funcdoc(f_c))
124    f_c(char c) -> char
125
126    >>> print(funcdoc(f_uc))
127    f_uc(unsigned char c) -> unsigned char
128
129    >>> print(funcdoc(f_sc))
130    f_sc(signed char c) -> signed char
131
132    >>> print(funcdoc(f_s))
133    f_s(short s) -> short
134
135    >>> print(funcdoc(f_us))
136    f_us(unsigned short s) -> unsigned short
137
138
139    >>> print(funcdoc(f_i))
140    f_i(int i) -> int
141
142    >>> print(funcdoc(f_ui))
143    f_ui(unsigned int i) -> unsigned int
144
145    >>> print(funcdoc(f_bint))
146    f_bint(bool i) -> bool
147
148
149    >>> print(funcdoc(f_l))
150    f_l(long l) -> long
151
152    >>> print(funcdoc(f_ul))
153    f_ul(unsigned long l) -> unsigned long
154
155
156    >>> print(funcdoc(f_L))
157    f_L(long long L) -> long long
158
159    >>> print(funcdoc(f_uL))
160    f_uL(unsigned long long L) -> unsigned long long
161
162
163    >>> print(funcdoc(f_f))
164    f_f(float f) -> float
165
166    >>> print(funcdoc(f_d))
167    f_d(double d) -> double
168
169    >>> print(funcdoc(f_D))
170    f_D(long double D) -> long double
171
172    >>> print(funcdoc(f_my_i))
173    f_my_i(MyInt i) -> MyInt
174
175    >>> print(funcdoc(f_my_f))
176    f_my_f(MyFloat f) -> MyFloat
177
178    >>> print(funcdoc(f_defexpr1))
179    f_defexpr1(int x=FLAG1, int y=FLAG2)
180
181    >>> print(funcdoc(f_defexpr2))
182    f_defexpr2(int x=FLAG1 | FLAG2, y=FLAG1 & FLAG2)
183
184    >>> print(funcdoc(f_defexpr3))
185    f_defexpr3(int x=Ext.CONST1, f=__builtins__.abs)
186
187    >>> print(funcdoc(f_defexpr4))
188    f_defexpr4(int x=(Ext.CONST1 + FLAG1) * Ext.CONST2)
189
190    >>> print(funcdoc(f_defexpr5))
191    f_defexpr5(int x=2 + 2)
192
193    >>> print(funcdoc(f_charptr_null))
194    f_charptr_null(char *s=NULL) -> char *
195"""
196
197cdef class Ext:
198
199    cdef public int  attr0
200    """attr0 docstring"""
201    cdef public      attr1
202    """attr1 docstring"""
203    cdef public list attr2
204    cdef public Ext attr3
205
206    """NOT attr3 docstring"""
207    cdef        int  attr4
208    cdef public int \
209        attr5
210    """attr5 docstring"""
211
212    CONST1, CONST2 = 1, 2
213
214    property prop0:
215        """prop0 docstring"""
216        def __get__(self):
217            return self.attr0
218
219    property prop1:
220        def __get__(self):
221            return self.attr1
222
223    property attr4:
224        """attr4 docstring"""
225        def __get__(self):
226            return self.attr4
227
228    def __init__(self, a, b, c=None):
229        pass
230
231    def a(self):
232        pass
233
234    def b(self, a, b, c):
235        pass
236
237    def c(self, a, b, c=1):
238        pass
239
240    def d(self, a, b, *, c = 88):
241        pass
242
243    def e(self, a, b, c = 88, **kwds):
244        pass
245
246    def f(self, a, b, *, c, d = 42):
247        pass
248
249    def g(self, a, b, *, c, d = 42, e = 17, f, **kwds):
250        pass
251
252    def h(self, a, b, *args, c, d = 42, e = 17, f, **kwds):
253        pass
254
255    def k(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds):
256        pass
257
258    def l(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds):
259        """Existing string"""
260        pass
261
262    def m(self, a=u'spam'):
263        pass
264
265    def n(self, a: int, b: float = 1.0, *args: tuple, **kwargs: dict) -> (None, True):
266        pass
267
268    cpdef int get_int(self):
269        return 0
270
271    cpdef float get_float(self):
272        return 0.0
273
274    cpdef str get_str(self):
275        """Existing string"""
276        return "string"
277
278    cpdef Ext clone(self):
279        return Ext(1,2)
280
281def foo():
282    pass
283
284def types(Ext a, int b, unsigned short c, float d, e):
285    pass
286
287def with_doc_1(a, b, c):
288    """Existing string"""
289    pass
290
291def with_doc_2(a, b, c):
292    """
293    Existing string
294    """
295    pass
296
297cpdef with_doc_3(a, b, c):
298    """Existing string"""
299    pass
300
301cpdef str with_doc_4(int a, str b, list c):
302    """
303    Existing string
304    """
305    return b
306
307def f_sd(str s='spam'):
308    return s
309
310cpdef str cf_sd(str s='spam'):
311    return s
312
313cpdef char f_c(char c):
314    return c
315
316cpdef unsigned char f_uc(unsigned char c):
317    return c
318
319cpdef signed char f_sc(signed char c):
320    return c
321
322
323cpdef short f_s(short s):
324    return s
325
326cpdef unsigned short f_us(unsigned short s):
327    return s
328
329
330cpdef int f_i(int i):
331    return i
332
333cpdef unsigned int f_ui(unsigned int i):
334    return i
335
336cpdef bint f_bint(bint i):
337    return i
338
339
340cpdef long f_l(long l):
341    return l
342
343cpdef unsigned long f_ul(unsigned long l):
344    return l
345
346
347cpdef long long f_L(long long L):
348    return L
349
350cpdef unsigned long long f_uL(unsigned long long L):
351    return L
352
353
354cpdef float f_f(float f):
355    return f
356
357cpdef double f_d(double d):
358    return d
359
360cpdef long double f_D(long double D):
361    return D
362
363ctypedef int MyInt
364cpdef MyInt f_my_i(MyInt i):
365    return i
366
367ctypedef float MyFloat
368cpdef MyFloat f_my_f(MyFloat f):
369    return f
370
371cdef enum:
372    FLAG1
373    FLAG2
374
375cpdef f_defexpr1(int x = FLAG1, int y = FLAG2):
376    pass
377
378cpdef f_defexpr2(int x = FLAG1 | FLAG2, y = FLAG1 & FLAG2):
379    pass
380
381cpdef f_defexpr3(int x = Ext.CONST1, f = __builtins__.abs):
382    pass
383
384cpdef f_defexpr4(int x = (Ext.CONST1 + FLAG1) * Ext.CONST2):
385    pass
386
387cpdef f_defexpr5(int x = 2+2):
388    pass
389
390cpdef (char*) f_charptr_null(char* s=NULL):
391    return s or b'abc'
392
393
394# no signatures for lambda functions
395lambda_foo = lambda x: 10
396lambda_bar = lambda x: 20
397
398
399cdef class Foo:
400    def m00(self, a: None) ->  None: pass
401    def m01(self, a: ...) ->  Ellipsis: pass
402    def m02(self, a: True, b: False) ->  bool: pass
403    def m03(self, a: 42, b: +42, c: -42) ->  int : pass  # XXX +42 -> 42
404    def m04(self, a: 3.14, b: +3.14, c: -3.14) -> float : pass
405    def m05(self, a: 1 + 2j, b: +2j, c: -2j) -> complex : pass
406    def m06(self, a: "abc", b: b"abc", c: u"abc") -> (str, bytes, unicode) : pass
407    def m07(self, a: [1, 2, 3], b: []) -> list: pass
408    def m08(self, a: (1, 2, 3), b: ()) -> tuple: pass
409    def m09(self, a: {1, 2, 3}, b: {i for i in ()}) -> set: pass
410    def m10(self, a: {1: 1, 2: 2, 3: 3}, b: {}) -> dict: pass
411   #def m11(self, a: [str(i) for i in range(3)]): pass  # Issue 1782
412    def m12(self, a: (str(i) for i in range(3))): pass
413    def m13(self, a: (str(i) for i in range(3) if bool(i))): pass
414    def m14(self, a: {str(i) for i in range(3)}): pass
415    def m15(self, a: {str(i) for i in range(3) if bool(i)}): pass
416    def m16(self, a: {str(i): id(i) for i in range(3)}): pass
417    def m17(self, a: {str(i): id(i) for i in range(3) if bool(i)}): pass
418    def m18(self, a: dict.update(x=42, **dict(), **{})): pass
419    def m19(self, a: sys is None, b: sys is not None): pass
420    def m20(self, a: sys in [], b: sys not in []): pass
421    def m21(self, a: (sys or sys) and sys, b: not (sys or sys)): pass
422    def m22(self, a: 42 if sys else None): pass
423    def m23(self, a: +int(), b: -int(), c: ~int()): pass
424    def m24(self, a: (1+int(2))*3+(4*int(5))**(1+0.0/1)): pass
425    def m25(self, a: list(range(3))[:]): pass
426    def m26(self, a: list(range(3))[1:]): pass
427    def m27(self, a: list(range(3))[:1]): pass
428    def m28(self, a: list(range(3))[::1]): pass
429    def m29(self, a: list(range(3))[0:1:1]): pass
430    def m30(self, a: list(range(3))[7, 3:2:1, ...]): pass
431    def m31(self, double[::1] a): pass
432
433__doc__ += ur"""
434>>> print(Foo.m00.__doc__)
435Foo.m00(self, a: None) -> None
436
437>>> print(Foo.m01.__doc__)
438Foo.m01(self, a: ...) -> Ellipsis
439
440>>> print(Foo.m02.__doc__)
441Foo.m02(self, a: True, b: False) -> bool
442
443>>> print(Foo.m03.__doc__)
444Foo.m03(self, a: 42, b: 42, c: -42) -> int
445
446>>> print(Foo.m04.__doc__)
447Foo.m04(self, a: 3.14, b: 3.14, c: -3.14) -> float
448
449>>> print(Foo.m05.__doc__)
450Foo.m05(self, a: 1 + 2j, b: +2j, c: -2j) -> complex
451
452>>> print(Foo.m06.__doc__)
453Foo.m06(self, a: 'abc', b: b'abc', c: u'abc') -> (str, bytes, unicode)
454
455>>> print(Foo.m07.__doc__)
456Foo.m07(self, a: [1, 2, 3], b: []) -> list
457
458>>> print(Foo.m08.__doc__)
459Foo.m08(self, a: (1, 2, 3), b: ()) -> tuple
460
461>>> print(Foo.m09.__doc__)
462Foo.m09(self, a: {1, 2, 3}, b: set()) -> set
463
464>>> print(Foo.m10.__doc__)
465Foo.m10(self, a: {1: 1, 2: 2, 3: 3}, b: {}) -> dict
466
467# >>> print(Foo.m11.__doc__)
468# Foo.m11(self, a: [str(i) for i in range(3)])
469
470>>> print(Foo.m12.__doc__)
471Foo.m12(self, a: (str(i) for i in range(3)))
472
473>>> print(Foo.m13.__doc__)
474Foo.m13(self, a: (str(i) for i in range(3) if bool(i)))
475
476>>> print(Foo.m14.__doc__)
477Foo.m14(self, a: {str(i) for i in range(3)})
478
479>>> print(Foo.m15.__doc__)
480Foo.m15(self, a: {str(i) for i in range(3) if bool(i)})
481
482>>> print(Foo.m16.__doc__)
483Foo.m16(self, a: {str(i): id(i) for i in range(3)})
484
485>>> print(Foo.m17.__doc__)
486Foo.m17(self, a: {str(i): id(i) for i in range(3) if bool(i)})
487
488>>> print(Foo.m18.__doc__)
489Foo.m18(self, a: dict.update(x=42, **dict()))
490
491>>> print(Foo.m19.__doc__)
492Foo.m19(self, a: sys is None, b: sys is not None)
493
494>>> print(Foo.m20.__doc__)
495Foo.m20(self, a: sys in [], b: sys not in [])
496
497>>> print(Foo.m21.__doc__)
498Foo.m21(self, a: (sys or sys) and sys, b: not (sys or sys))
499
500>>> print(Foo.m22.__doc__)
501Foo.m22(self, a: 42 if sys else None)
502
503>>> print(Foo.m23.__doc__)
504Foo.m23(self, a: +int(), b: -int(), c: ~int())
505
506>>> print(Foo.m24.__doc__)
507Foo.m24(self, a: (1 + int(2)) * 3 + (4 * int(5)) ** (1 + 0.0 / 1))
508
509>>> print(Foo.m25.__doc__)
510Foo.m25(self, a: list(range(3))[:])
511
512>>> print(Foo.m26.__doc__)
513Foo.m26(self, a: list(range(3))[1:])
514
515>>> print(Foo.m27.__doc__)
516Foo.m27(self, a: list(range(3))[:1])
517
518>>> print(Foo.m28.__doc__)
519Foo.m28(self, a: list(range(3))[::1])
520
521>>> print(Foo.m29.__doc__)
522Foo.m29(self, a: list(range(3))[0:1:1])
523
524>>> print(Foo.m30.__doc__)
525Foo.m30(self, a: list(range(3))[7, 3:2:1, ...])
526
527>>> print(Foo.m31.__doc__)
528Foo.m31(self, double[::1] a)
529"""
530