-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
/
Copy pathtopics.py
12859 lines (9845 loc) · 522 KB
/
topics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Autogenerated by Sphinx on Wed Mar 19 18:40:00 2025
# as part of the release process.
topics = {
'assert': r'''The "assert" statement
**********************
Assert statements are a convenient way to insert debugging assertions
into a program:
assert_stmt: "assert" expression ["," expression]
The simple form, "assert expression", is equivalent to
if __debug__:
if not expression: raise AssertionError
The extended form, "assert expression1, expression2", is equivalent to
if __debug__:
if not expression1: raise AssertionError(expression2)
These equivalences assume that "__debug__" and "AssertionError" refer
to the built-in variables with those names. In the current
implementation, the built-in variable "__debug__" is "True" under
normal circumstances, "False" when optimization is requested (command
line option "-O"). The current code generator emits no code for an
"assert" statement when optimization is requested at compile time.
Note that it is unnecessary to include the source code for the
expression that failed in the error message; it will be displayed as
part of the stack trace.
Assignments to "__debug__" are illegal. The value for the built-in
variable is determined when the interpreter starts.
''',
'assignment': r'''Assignment statements
*********************
Assignment statements are used to (re)bind names to values and to
modify attributes or items of mutable objects:
assignment_stmt: (target_list "=")+ (starred_expression | yield_expression)
target_list: target ("," target)* [","]
target: identifier
| "(" [target_list] ")"
| "[" [target_list] "]"
| attributeref
| subscription
| slicing
| "*" target
(See section Primaries for the syntax definitions for *attributeref*,
*subscription*, and *slicing*.)
An assignment statement evaluates the expression list (remember that
this can be a single expression or a comma-separated list, the latter
yielding a tuple) and assigns the single resulting object to each of
the target lists, from left to right.
Assignment is defined recursively depending on the form of the target
(list). When a target is part of a mutable object (an attribute
reference, subscription or slicing), the mutable object must
ultimately perform the assignment and decide about its validity, and
may raise an exception if the assignment is unacceptable. The rules
observed by various types and the exceptions raised are given with the
definition of the object types (see section The standard type
hierarchy).
Assignment of an object to a target list, optionally enclosed in
parentheses or square brackets, is recursively defined as follows.
* If the target list is a single target with no trailing comma,
optionally in parentheses, the object is assigned to that target.
* Else:
* If the target list contains one target prefixed with an asterisk,
called a “starred” target: The object must be an iterable with at
least as many items as there are targets in the target list, minus
one. The first items of the iterable are assigned, from left to
right, to the targets before the starred target. The final items
of the iterable are assigned to the targets after the starred
target. A list of the remaining items in the iterable is then
assigned to the starred target (the list can be empty).
* Else: The object must be an iterable with the same number of items
as there are targets in the target list, and the items are
assigned, from left to right, to the corresponding targets.
Assignment of an object to a single target is recursively defined as
follows.
* If the target is an identifier (name):
* If the name does not occur in a "global" or "nonlocal" statement
in the current code block: the name is bound to the object in the
current local namespace.
* Otherwise: the name is bound to the object in the global namespace
or the outer namespace determined by "nonlocal", respectively.
The name is rebound if it was already bound. This may cause the
reference count for the object previously bound to the name to reach
zero, causing the object to be deallocated and its destructor (if it
has one) to be called.
* If the target is an attribute reference: The primary expression in
the reference is evaluated. It should yield an object with
assignable attributes; if this is not the case, "TypeError" is
raised. That object is then asked to assign the assigned object to
the given attribute; if it cannot perform the assignment, it raises
an exception (usually but not necessarily "AttributeError").
Note: If the object is a class instance and the attribute reference
occurs on both sides of the assignment operator, the right-hand side
expression, "a.x" can access either an instance attribute or (if no
instance attribute exists) a class attribute. The left-hand side
target "a.x" is always set as an instance attribute, creating it if
necessary. Thus, the two occurrences of "a.x" do not necessarily
refer to the same attribute: if the right-hand side expression
refers to a class attribute, the left-hand side creates a new
instance attribute as the target of the assignment:
class Cls:
x = 3 # class variable
inst = Cls()
inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3
This description does not necessarily apply to descriptor
attributes, such as properties created with "property()".
* If the target is a subscription: The primary expression in the
reference is evaluated. It should yield either a mutable sequence
object (such as a list) or a mapping object (such as a dictionary).
Next, the subscript expression is evaluated.
If the primary is a mutable sequence object (such as a list), the
subscript must yield an integer. If it is negative, the sequence’s
length is added to it. The resulting value must be a nonnegative
integer less than the sequence’s length, and the sequence is asked
to assign the assigned object to its item with that index. If the
index is out of range, "IndexError" is raised (assignment to a
subscripted sequence cannot add new items to a list).
If the primary is a mapping object (such as a dictionary), the
subscript must have a type compatible with the mapping’s key type,
and the mapping is then asked to create a key/value pair which maps
the subscript to the assigned object. This can either replace an
existing key/value pair with the same key value, or insert a new
key/value pair (if no key with the same value existed).
For user-defined objects, the "__setitem__()" method is called with
appropriate arguments.
* If the target is a slicing: The primary expression in the reference
is evaluated. It should yield a mutable sequence object (such as a
list). The assigned object should be a sequence object of the same
type. Next, the lower and upper bound expressions are evaluated,
insofar they are present; defaults are zero and the sequence’s
length. The bounds should evaluate to integers. If either bound is
negative, the sequence’s length is added to it. The resulting
bounds are clipped to lie between zero and the sequence’s length,
inclusive. Finally, the sequence object is asked to replace the
slice with the items of the assigned sequence. The length of the
slice may be different from the length of the assigned sequence,
thus changing the length of the target sequence, if the target
sequence allows it.
**CPython implementation detail:** In the current implementation, the
syntax for targets is taken to be the same as for expressions, and
invalid syntax is rejected during the code generation phase, causing
less detailed error messages.
Although the definition of assignment implies that overlaps between
the left-hand side and the right-hand side are ‘simultaneous’ (for
example "a, b = b, a" swaps two variables), overlaps *within* the
collection of assigned-to variables occur left-to-right, sometimes
resulting in confusion. For instance, the following program prints
"[0, 2]":
x = [0, 1]
i = 0
i, x[i] = 1, 2 # i is updated, then x[i] is updated
print(x)
See also:
**PEP 3132** - Extended Iterable Unpacking
The specification for the "*target" feature.
Augmented assignment statements
===============================
Augmented assignment is the combination, in a single statement, of a
binary operation and an assignment statement:
augmented_assignment_stmt: augtarget augop (expression_list | yield_expression)
augtarget: identifier | attributeref | subscription | slicing
augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
| ">>=" | "<<=" | "&=" | "^=" | "|="
(See section Primaries for the syntax definitions of the last three
symbols.)
An augmented assignment evaluates the target (which, unlike normal
assignment statements, cannot be an unpacking) and the expression
list, performs the binary operation specific to the type of assignment
on the two operands, and assigns the result to the original target.
The target is only evaluated once.
An augmented assignment statement like "x += 1" can be rewritten as "x
= x + 1" to achieve a similar, but not exactly equal effect. In the
augmented version, "x" is only evaluated once. Also, when possible,
the actual operation is performed *in-place*, meaning that rather than
creating a new object and assigning that to the target, the old object
is modified instead.
Unlike normal assignments, augmented assignments evaluate the left-
hand side *before* evaluating the right-hand side. For example, "a[i]
+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs
the addition, and lastly, it writes the result back to "a[i]".
With the exception of assigning to tuples and multiple targets in a
single statement, the assignment done by augmented assignment
statements is handled the same way as normal assignments. Similarly,
with the exception of the possible *in-place* behavior, the binary
operation performed by augmented assignment is the same as the normal
binary operations.
For targets which are attribute references, the same caveat about
class and instance attributes applies as for regular assignments.
Annotated assignment statements
===============================
*Annotation* assignment is the combination, in a single statement, of
a variable or attribute annotation and an optional assignment
statement:
annotated_assignment_stmt: augtarget ":" expression
["=" (starred_expression | yield_expression)]
The difference from normal Assignment statements is that only a single
target is allowed.
The assignment target is considered “simple” if it consists of a
single name that is not enclosed in parentheses. For simple assignment
targets, if in class or module scope, the annotations are gathered in
a lazily evaluated annotation scope. The annotations can be evaluated
using the "__annotations__" attribute of a class or module, or using
the facilities in the "annotationlib" module.
If the assignment target is not simple (an attribute, subscript node,
or parenthesized name), the annotation is never evaluated.
If a name is annotated in a function scope, then this name is local
for that scope. Annotations are never evaluated and stored in function
scopes.
If the right hand side is present, an annotated assignment performs
the actual assignment as if there was no annotation present. If the
right hand side is not present for an expression target, then the
interpreter evaluates the target except for the last "__setitem__()"
or "__setattr__()" call.
See also:
**PEP 526** - Syntax for Variable Annotations
The proposal that added syntax for annotating the types of
variables (including class variables and instance variables),
instead of expressing them through comments.
**PEP 484** - Type hints
The proposal that added the "typing" module to provide a standard
syntax for type annotations that can be used in static analysis
tools and IDEs.
Changed in version 3.8: Now annotated assignments allow the same
expressions in the right hand side as regular assignments. Previously,
some expressions (like un-parenthesized tuple expressions) caused a
syntax error.
Changed in version 3.14: Annotations are now lazily evaluated in a
separate annotation scope. If the assignment target is not simple,
annotations are never evaluated.
''',
'assignment-expressions': r'''Assignment expressions
**********************
assignment_expression: [identifier ":="] expression
An assignment expression (sometimes also called a “named expression”
or “walrus”) assigns an "expression" to an "identifier", while also
returning the value of the "expression".
One common use case is when handling matched regular expressions:
if matching := pattern.search(data):
do_something(matching)
Or, when processing a file stream in chunks:
while chunk := file.read(9000):
process(chunk)
Assignment expressions must be surrounded by parentheses when used as
expression statements and when used as sub-expressions in slicing,
conditional, lambda, keyword-argument, and comprehension-if
expressions and in "assert", "with", and "assignment" statements. In
all other places where they can be used, parentheses are not required,
including in "if" and "while" statements.
Added in version 3.8: See **PEP 572** for more details about
assignment expressions.
''',
'async': r'''Coroutines
**********
Added in version 3.5.
Coroutine function definition
=============================
async_funcdef: [decorators] "async" "def" funcname "(" [parameter_list] ")"
["->" expression] ":" suite
Execution of Python coroutines can be suspended and resumed at many
points (see *coroutine*). "await" expressions, "async for" and "async
with" can only be used in the body of a coroutine function.
Functions defined with "async def" syntax are always coroutine
functions, even if they do not contain "await" or "async" keywords.
It is a "SyntaxError" to use a "yield from" expression inside the body
of a coroutine function.
An example of a coroutine function:
async def func(param1, param2):
do_stuff()
await some_coroutine()
Changed in version 3.7: "await" and "async" are now keywords;
previously they were only treated as such inside the body of a
coroutine function.
The "async for" statement
=========================
async_for_stmt: "async" for_stmt
An *asynchronous iterable* provides an "__aiter__" method that
directly returns an *asynchronous iterator*, which can call
asynchronous code in its "__anext__" method.
The "async for" statement allows convenient iteration over
asynchronous iterables.
The following code:
async for TARGET in ITER:
SUITE
else:
SUITE2
Is semantically equivalent to:
iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True
while running:
try:
TARGET = await type(iter).__anext__(iter)
except StopAsyncIteration:
running = False
else:
SUITE
else:
SUITE2
See also "__aiter__()" and "__anext__()" for details.
It is a "SyntaxError" to use an "async for" statement outside the body
of a coroutine function.
The "async with" statement
==========================
async_with_stmt: "async" with_stmt
An *asynchronous context manager* is a *context manager* that is able
to suspend execution in its *enter* and *exit* methods.
The following code:
async with EXPRESSION as TARGET:
SUITE
is semantically equivalent to:
manager = (EXPRESSION)
aenter = type(manager).__aenter__
aexit = type(manager).__aexit__
value = await aenter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not await aexit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
await aexit(manager, None, None, None)
See also "__aenter__()" and "__aexit__()" for details.
It is a "SyntaxError" to use an "async with" statement outside the
body of a coroutine function.
See also:
**PEP 492** - Coroutines with async and await syntax
The proposal that made coroutines a proper standalone concept in
Python, and added supporting syntax.
''',
'atom-identifiers': r'''Identifiers (Names)
*******************
An identifier occurring as an atom is a name. See section Identifiers
and keywords for lexical definition and section Naming and binding for
documentation of naming and binding.
When the name is bound to an object, evaluation of the atom yields
that object. When a name is not bound, an attempt to evaluate it
raises a "NameError" exception.
Private name mangling
=====================
When an identifier that textually occurs in a class definition begins
with two or more underscore characters and does not end in two or more
underscores, it is considered a *private name* of that class.
See also: The class specifications.
More precisely, private names are transformed to a longer form before
code is generated for them. If the transformed name is longer than
255 characters, implementation-defined truncation may happen.
The transformation is independent of the syntactical context in which
the identifier is used but only the following private identifiers are
mangled:
* Any name used as the name of a variable that is assigned or read or
any name of an attribute being accessed.
The "__name__" attribute of nested functions, classes, and type
aliases is however not mangled.
* The name of imported modules, e.g., "__spam" in "import __spam". If
the module is part of a package (i.e., its name contains a dot), the
name is *not* mangled, e.g., the "__foo" in "import __foo.bar" is
not mangled.
* The name of an imported member, e.g., "__f" in "from spam import
__f".
The transformation rule is defined as follows:
* The class name, with leading underscores removed and a single
leading underscore inserted, is inserted in front of the identifier,
e.g., the identifier "__spam" occurring in a class named "Foo",
"_Foo" or "__Foo" is transformed to "_Foo__spam".
* If the class name consists only of underscores, the transformation
is the identity, e.g., the identifier "__spam" occurring in a class
named "_" or "__" is left as is.
''',
'atom-literals': r'''Literals
********
Python supports string and bytes literals and various numeric
literals:
literal: stringliteral | bytesliteral
| integer | floatnumber | imagnumber
Evaluation of a literal yields an object of the given type (string,
bytes, integer, floating-point number, complex number) with the given
value. The value may be approximated in the case of floating-point
and imaginary (complex) literals. See section Literals for details.
All literals correspond to immutable data types, and hence the
object’s identity is less important than its value. Multiple
evaluations of literals with the same value (either the same
occurrence in the program text or a different occurrence) may obtain
the same object or a different object with the same value.
''',
'attribute-access': r'''Customizing attribute access
****************************
The following methods can be defined to customize the meaning of
attribute access (use of, assignment to, or deletion of "x.name") for
class instances.
object.__getattr__(self, name)
Called when the default attribute access fails with an
"AttributeError" (either "__getattribute__()" raises an
"AttributeError" because *name* is not an instance attribute or an
attribute in the class tree for "self"; or "__get__()" of a *name*
property raises "AttributeError"). This method should either
return the (computed) attribute value or raise an "AttributeError"
exception. The "object" class itself does not provide this method.
Note that if the attribute is found through the normal mechanism,
"__getattr__()" is not called. (This is an intentional asymmetry
between "__getattr__()" and "__setattr__()".) This is done both for
efficiency reasons and because otherwise "__getattr__()" would have
no way to access other attributes of the instance. Note that at
least for instance variables, you can take total control by not
inserting any values in the instance attribute dictionary (but
instead inserting them in another object). See the
"__getattribute__()" method below for a way to actually get total
control over attribute access.
object.__getattribute__(self, name)
Called unconditionally to implement attribute accesses for
instances of the class. If the class also defines "__getattr__()",
the latter will not be called unless "__getattribute__()" either
calls it explicitly or raises an "AttributeError". This method
should return the (computed) attribute value or raise an
"AttributeError" exception. In order to avoid infinite recursion in
this method, its implementation should always call the base class
method with the same name to access any attributes it needs, for
example, "object.__getattribute__(self, name)".
Note:
This method may still be bypassed when looking up special methods
as the result of implicit invocation via language syntax or
built-in functions. See Special method lookup.
For certain sensitive attribute accesses, raises an auditing event
"object.__getattr__" with arguments "obj" and "name".
object.__setattr__(self, name, value)
Called when an attribute assignment is attempted. This is called
instead of the normal mechanism (i.e. store the value in the
instance dictionary). *name* is the attribute name, *value* is the
value to be assigned to it.
If "__setattr__()" wants to assign to an instance attribute, it
should call the base class method with the same name, for example,
"object.__setattr__(self, name, value)".
For certain sensitive attribute assignments, raises an auditing
event "object.__setattr__" with arguments "obj", "name", "value".
object.__delattr__(self, name)
Like "__setattr__()" but for attribute deletion instead of
assignment. This should only be implemented if "del obj.name" is
meaningful for the object.
For certain sensitive attribute deletions, raises an auditing event
"object.__delattr__" with arguments "obj" and "name".
object.__dir__(self)
Called when "dir()" is called on the object. An iterable must be
returned. "dir()" converts the returned iterable to a list and
sorts it.
Customizing module attribute access
===================================
Special names "__getattr__" and "__dir__" can be also used to
customize access to module attributes. The "__getattr__" function at
the module level should accept one argument which is the name of an
attribute and return the computed value or raise an "AttributeError".
If an attribute is not found on a module object through the normal
lookup, i.e. "object.__getattribute__()", then "__getattr__" is
searched in the module "__dict__" before raising an "AttributeError".
If found, it is called with the attribute name and the result is
returned.
The "__dir__" function should accept no arguments, and return an
iterable of strings that represents the names accessible on module. If
present, this function overrides the standard "dir()" search on a
module.
For a more fine grained customization of the module behavior (setting
attributes, properties, etc.), one can set the "__class__" attribute
of a module object to a subclass of "types.ModuleType". For example:
import sys
from types import ModuleType
class VerboseModule(ModuleType):
def __repr__(self):
return f'Verbose {self.__name__}'
def __setattr__(self, attr, value):
print(f'Setting {attr}...')
super().__setattr__(attr, value)
sys.modules[__name__].__class__ = VerboseModule
Note:
Defining module "__getattr__" and setting module "__class__" only
affect lookups made using the attribute access syntax – directly
accessing the module globals (whether by code within the module, or
via a reference to the module’s globals dictionary) is unaffected.
Changed in version 3.5: "__class__" module attribute is now writable.
Added in version 3.7: "__getattr__" and "__dir__" module attributes.
See also:
**PEP 562** - Module __getattr__ and __dir__
Describes the "__getattr__" and "__dir__" functions on modules.
Implementing Descriptors
========================
The following methods only apply when an instance of the class
containing the method (a so-called *descriptor* class) appears in an
*owner* class (the descriptor must be in either the owner’s class
dictionary or in the class dictionary for one of its parents). In the
examples below, “the attribute” refers to the attribute whose name is
the key of the property in the owner class’ "__dict__". The "object"
class itself does not implement any of these protocols.
object.__get__(self, instance, owner=None)
Called to get the attribute of the owner class (class attribute
access) or of an instance of that class (instance attribute
access). The optional *owner* argument is the owner class, while
*instance* is the instance that the attribute was accessed through,
or "None" when the attribute is accessed through the *owner*.
This method should return the computed attribute value or raise an
"AttributeError" exception.
**PEP 252** specifies that "__get__()" is callable with one or two
arguments. Python’s own built-in descriptors support this
specification; however, it is likely that some third-party tools
have descriptors that require both arguments. Python’s own
"__getattribute__()" implementation always passes in both arguments
whether they are required or not.
object.__set__(self, instance, value)
Called to set the attribute on an instance *instance* of the owner
class to a new value, *value*.
Note, adding "__set__()" or "__delete__()" changes the kind of
descriptor to a “data descriptor”. See Invoking Descriptors for
more details.
object.__delete__(self, instance)
Called to delete the attribute on an instance *instance* of the
owner class.
Instances of descriptors may also have the "__objclass__" attribute
present:
object.__objclass__
The attribute "__objclass__" is interpreted by the "inspect" module
as specifying the class where this object was defined (setting this
appropriately can assist in runtime introspection of dynamic class
attributes). For callables, it may indicate that an instance of the
given type (or a subclass) is expected or required as the first
positional argument (for example, CPython sets this attribute for
unbound methods that are implemented in C).
Invoking Descriptors
====================
In general, a descriptor is an object attribute with “binding
behavior”, one whose attribute access has been overridden by methods
in the descriptor protocol: "__get__()", "__set__()", and
"__delete__()". If any of those methods are defined for an object, it
is said to be a descriptor.
The default behavior for attribute access is to get, set, or delete
the attribute from an object’s dictionary. For instance, "a.x" has a
lookup chain starting with "a.__dict__['x']", then
"type(a).__dict__['x']", and continuing through the base classes of
"type(a)" excluding metaclasses.
However, if the looked-up value is an object defining one of the
descriptor methods, then Python may override the default behavior and
invoke the descriptor method instead. Where this occurs in the
precedence chain depends on which descriptor methods were defined and
how they were called.
The starting point for descriptor invocation is a binding, "a.x". How
the arguments are assembled depends on "a":
Direct Call
The simplest and least common call is when user code directly
invokes a descriptor method: "x.__get__(a)".
Instance Binding
If binding to an object instance, "a.x" is transformed into the
call: "type(a).__dict__['x'].__get__(a, type(a))".
Class Binding
If binding to a class, "A.x" is transformed into the call:
"A.__dict__['x'].__get__(None, A)".
Super Binding
A dotted lookup such as "super(A, a).x" searches
"a.__class__.__mro__" for a base class "B" following "A" and then
returns "B.__dict__['x'].__get__(a, A)". If not a descriptor, "x"
is returned unchanged.
For instance bindings, the precedence of descriptor invocation depends
on which descriptor methods are defined. A descriptor can define any
combination of "__get__()", "__set__()" and "__delete__()". If it
does not define "__get__()", then accessing the attribute will return
the descriptor object itself unless there is a value in the object’s
instance dictionary. If the descriptor defines "__set__()" and/or
"__delete__()", it is a data descriptor; if it defines neither, it is
a non-data descriptor. Normally, data descriptors define both
"__get__()" and "__set__()", while non-data descriptors have just the
"__get__()" method. Data descriptors with "__get__()" and "__set__()"
(and/or "__delete__()") defined always override a redefinition in an
instance dictionary. In contrast, non-data descriptors can be
overridden by instances.
Python methods (including those decorated with "@staticmethod" and
"@classmethod") are implemented as non-data descriptors. Accordingly,
instances can redefine and override methods. This allows individual
instances to acquire behaviors that differ from other instances of the
same class.
The "property()" function is implemented as a data descriptor.
Accordingly, instances cannot override the behavior of a property.
__slots__
=========
*__slots__* allow us to explicitly declare data members (like
properties) and deny the creation of "__dict__" and *__weakref__*
(unless explicitly declared in *__slots__* or available in a parent.)
The space saved over using "__dict__" can be significant. Attribute
lookup speed can be significantly improved as well.
object.__slots__
This class variable can be assigned a string, iterable, or sequence
of strings with variable names used by instances. *__slots__*
reserves space for the declared variables and prevents the
automatic creation of "__dict__" and *__weakref__* for each
instance.
Notes on using *__slots__*:
* When inheriting from a class without *__slots__*, the "__dict__" and
*__weakref__* attribute of the instances will always be accessible.
* Without a "__dict__" variable, instances cannot be assigned new
variables not listed in the *__slots__* definition. Attempts to
assign to an unlisted variable name raises "AttributeError". If
dynamic assignment of new variables is desired, then add
"'__dict__'" to the sequence of strings in the *__slots__*
declaration.
* Without a *__weakref__* variable for each instance, classes defining
*__slots__* do not support "weak references" to its instances. If
weak reference support is needed, then add "'__weakref__'" to the
sequence of strings in the *__slots__* declaration.
* *__slots__* are implemented at the class level by creating
descriptors for each variable name. As a result, class attributes
cannot be used to set default values for instance variables defined
by *__slots__*; otherwise, the class attribute would overwrite the
descriptor assignment.
* The action of a *__slots__* declaration is not limited to the class
where it is defined. *__slots__* declared in parents are available
in child classes. However, instances of a child subclass will get a
"__dict__" and *__weakref__* unless the subclass also defines
*__slots__* (which should only contain names of any *additional*
slots).
* If a class defines a slot also defined in a base class, the instance
variable defined by the base class slot is inaccessible (except by
retrieving its descriptor directly from the base class). This
renders the meaning of the program undefined. In the future, a
check may be added to prevent this.
* "TypeError" will be raised if nonempty *__slots__* are defined for a
class derived from a ""variable-length" built-in type" such as
"int", "bytes", and "tuple".
* Any non-string *iterable* may be assigned to *__slots__*.
* If a "dictionary" is used to assign *__slots__*, the dictionary keys
will be used as the slot names. The values of the dictionary can be
used to provide per-attribute docstrings that will be recognised by
"inspect.getdoc()" and displayed in the output of "help()".
* "__class__" assignment works only if both classes have the same
*__slots__*.
* Multiple inheritance with multiple slotted parent classes can be
used, but only one parent is allowed to have attributes created by
slots (the other bases must have empty slot layouts) - violations
raise "TypeError".
* If an *iterator* is used for *__slots__* then a *descriptor* is
created for each of the iterator’s values. However, the *__slots__*
attribute will be an empty iterator.
''',
'attribute-references': r'''Attribute references
********************
An attribute reference is a primary followed by a period and a name:
attributeref: primary "." identifier
The primary must evaluate to an object of a type that supports
attribute references, which most objects do. This object is then
asked to produce the attribute whose name is the identifier. The type
and value produced is determined by the object. Multiple evaluations
of the same attribute reference may yield different objects.
This production can be customized by overriding the
"__getattribute__()" method or the "__getattr__()" method. The
"__getattribute__()" method is called first and either returns a value
or raises "AttributeError" if the attribute is not available.
If an "AttributeError" is raised and the object has a "__getattr__()"
method, that method is called as a fallback.
''',
'augassign': r'''Augmented assignment statements
*******************************
Augmented assignment is the combination, in a single statement, of a
binary operation and an assignment statement:
augmented_assignment_stmt: augtarget augop (expression_list | yield_expression)
augtarget: identifier | attributeref | subscription | slicing
augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
| ">>=" | "<<=" | "&=" | "^=" | "|="
(See section Primaries for the syntax definitions of the last three
symbols.)
An augmented assignment evaluates the target (which, unlike normal
assignment statements, cannot be an unpacking) and the expression
list, performs the binary operation specific to the type of assignment
on the two operands, and assigns the result to the original target.
The target is only evaluated once.
An augmented assignment statement like "x += 1" can be rewritten as "x
= x + 1" to achieve a similar, but not exactly equal effect. In the
augmented version, "x" is only evaluated once. Also, when possible,
the actual operation is performed *in-place*, meaning that rather than
creating a new object and assigning that to the target, the old object
is modified instead.
Unlike normal assignments, augmented assignments evaluate the left-
hand side *before* evaluating the right-hand side. For example, "a[i]
+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs
the addition, and lastly, it writes the result back to "a[i]".
With the exception of assigning to tuples and multiple targets in a
single statement, the assignment done by augmented assignment
statements is handled the same way as normal assignments. Similarly,
with the exception of the possible *in-place* behavior, the binary
operation performed by augmented assignment is the same as the normal
binary operations.
For targets which are attribute references, the same caveat about
class and instance attributes applies as for regular assignments.
''',
'await': r'''Await expression
****************
Suspend the execution of *coroutine* on an *awaitable* object. Can
only be used inside a *coroutine function*.
await_expr: "await" primary
Added in version 3.5.
''',
'binary': r'''Binary arithmetic operations
****************************
The binary arithmetic operations have the conventional priority
levels. Note that some of these operations also apply to certain non-
numeric types. Apart from the power operator, there are only two
levels, one for multiplicative operators and one for additive
operators:
m_expr: u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
m_expr "//" u_expr | m_expr "/" u_expr |
m_expr "%" u_expr
a_expr: m_expr | a_expr "+" m_expr | a_expr "-" m_expr
The "*" (multiplication) operator yields the product of its arguments.
The arguments must either both be numbers, or one argument must be an
integer and the other must be a sequence. In the former case, the
numbers are converted to a common real type and then multiplied
together. In the latter case, sequence repetition is performed; a
negative repetition factor yields an empty sequence.
This operation can be customized using the special "__mul__()" and
"__rmul__()" methods.
Changed in version 3.14: If only one operand is a complex number, the
other operand is converted to a floating-point number.
The "@" (at) operator is intended to be used for matrix
multiplication. No builtin Python types implement this operator.
This operation can be customized using the special "__matmul__()" and
"__rmatmul__()" methods.
Added in version 3.5.
The "/" (division) and "//" (floor division) operators yield the
quotient of their arguments. The numeric arguments are first
converted to a common type. Division of integers yields a float, while
floor division of integers results in an integer; the result is that
of mathematical division with the ‘floor’ function applied to the
result. Division by zero raises the "ZeroDivisionError" exception.
The division operation can be customized using the special
"__truediv__()" and "__rtruediv__()" methods. The floor division
operation can be customized using the special "__floordiv__()" and
"__rfloordiv__()" methods.
The "%" (modulo) operator yields the remainder from the division of
the first argument by the second. The numeric arguments are first
converted to a common type. A zero right argument raises the
"ZeroDivisionError" exception. The arguments may be floating-point
numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +
0.34".) The modulo operator always yields a result with the same sign
as its second operand (or zero); the absolute value of the result is
strictly smaller than the absolute value of the second operand [1].
The floor division and modulo operators are connected by the following
identity: "x == (x//y)*y + (x%y)". Floor division and modulo are also
connected with the built-in function "divmod()": "divmod(x, y) ==
(x//y, x%y)". [2].
In addition to performing the modulo operation on numbers, the "%"
operator is also overloaded by string objects to perform old-style
string formatting (also known as interpolation). The syntax for
string formatting is described in the Python Library Reference,
section printf-style String Formatting.
The *modulo* operation can be customized using the special "__mod__()"
and "__rmod__()" methods.
The floor division operator, the modulo operator, and the "divmod()"
function are not defined for complex numbers. Instead, convert to a
floating-point number using the "abs()" function if appropriate.
The "+" (addition) operator yields the sum of its arguments. The
arguments must either both be numbers or both be sequences of the same
type. In the former case, the numbers are converted to a common real
type and then added together. In the latter case, the sequences are
concatenated.
This operation can be customized using the special "__add__()" and
"__radd__()" methods.
Changed in version 3.14: If only one operand is a complex number, the
other operand is converted to a floating-point number.
The "-" (subtraction) operator yields the difference of its arguments.
The numeric arguments are first converted to a common real type.