66from typing import TYPE_CHECKING
77from typing import Any
88from typing import Callable
9+ from typing import Optional
910
1011from ddtrace .internal .compat import iteritems
1112
@@ -52,13 +53,15 @@ def add_aspect(op1, op2):
5253
5354
5455def str_aspect (orig_function , flag_added_args , * args , ** kwargs ):
55- # type: (Callable, int, Any, Any) -> str
56- if orig_function != builtin_str :
57- if flag_added_args > 0 :
58- args = args [flag_added_args :]
59- return orig_function (* args , ** kwargs )
60-
61- result = builtin_str (* args , ** kwargs )
56+ # type: (Optional[Callable], int, Any, Any) -> str
57+ if orig_function :
58+ if orig_function != builtin_str :
59+ if flag_added_args > 0 :
60+ args = args [flag_added_args :]
61+ return orig_function (* args , ** kwargs )
62+ result = builtin_str (* args , ** kwargs )
63+ else :
64+ result = args [0 ].str (* args [1 :], ** kwargs )
6265
6366 if isinstance (args [0 ], TEXT_TYPES ) and is_pyobject_tainted (args [0 ]):
6467 try :
@@ -76,13 +79,16 @@ def str_aspect(orig_function, flag_added_args, *args, **kwargs):
7679
7780
7881def bytes_aspect (orig_function , flag_added_args , * args , ** kwargs ):
79- # type: (Callable, int, Any, Any) -> bytes
80- if orig_function != builtin_bytes :
81- if flag_added_args > 0 :
82- args = args [flag_added_args :]
83- return orig_function (* args , ** kwargs )
82+ # type: (Optional[Callable], int, Any, Any) -> bytes
83+ if orig_function :
84+ if orig_function != builtin_bytes :
85+ if flag_added_args > 0 :
86+ args = args [flag_added_args :]
87+ return orig_function (* args , ** kwargs )
88+ result = builtin_bytes (* args , ** kwargs )
89+ else :
90+ result = args [0 ].bytes (* args [1 :], ** kwargs )
8491
85- result = builtin_bytes (* args , ** kwargs )
8692 if isinstance (args [0 ], TEXT_TYPES ) and is_pyobject_tainted (args [0 ]):
8793 try :
8894 taint_pyobject_with_ranges (result , tuple (get_ranges (args [0 ])))
@@ -92,13 +98,16 @@ def bytes_aspect(orig_function, flag_added_args, *args, **kwargs):
9298
9399
94100def bytearray_aspect (orig_function , flag_added_args , * args , ** kwargs ):
95- # type: (Callable, int, Any, Any) -> bytearray
96- if orig_function != builtin_bytearray :
97- if flag_added_args > 0 :
98- args = args [flag_added_args :]
99- return orig_function (* args , ** kwargs )
101+ # type: (Optional[Callable], int, Any, Any) -> bytearray
102+ if orig_function :
103+ if orig_function != builtin_bytearray :
104+ if flag_added_args > 0 :
105+ args = args [flag_added_args :]
106+ return orig_function (* args , ** kwargs )
107+ result = builtin_bytearray (* args , ** kwargs )
108+ else :
109+ result = args [0 ].bytearray (* args [1 :], ** kwargs )
100110
101- result = builtin_bytearray (* args , ** kwargs )
102111 if isinstance (args [0 ], TEXT_TYPES ) and is_pyobject_tainted (args [0 ]):
103112 try :
104113 taint_pyobject_with_ranges (result , tuple (get_ranges (args [0 ])))
@@ -108,7 +117,9 @@ def bytearray_aspect(orig_function, flag_added_args, *args, **kwargs):
108117
109118
110119def join_aspect (orig_function , flag_added_args , * args , ** kwargs ):
111- # type: (Callable, int, Any, Any) -> Any
120+ # type: (Optional[Callable], int, Any, Any) -> Any
121+ if not orig_function :
122+ orig_function = args [0 ].join
112123 if not isinstance (orig_function , BuiltinFunctionType ):
113124 if flag_added_args > 0 :
114125 args = args [flag_added_args :]
@@ -158,16 +169,22 @@ def slice_aspect(candidate_text, start, stop, step) -> Any:
158169
159170
160171def bytearray_extend_aspect (orig_function , flag_added_args , * args , ** kwargs ):
161- # type: (Callable, int, Any, Any) -> Any
162- if not isinstance (orig_function , BuiltinFunctionType ):
172+ # type: (Optional[ Callable] , int, Any, Any) -> Any
173+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
163174 if flag_added_args > 0 :
164175 args = args [flag_added_args :]
165176 return orig_function (* args , ** kwargs )
166177
178+ if len (args ) < 2 :
179+ # If we're not receiving at least 2 arguments, means the call was
180+ # ``x.extend()`` and not ``x.extend(y)``
181+ # so either not the extend we're looking for, or no changes in taint ranges.
182+ return args [0 ].extend (* args [1 :], ** kwargs )
183+
167184 op1 = args [0 ]
168185 op2 = args [1 ]
169186 if not isinstance (op1 , bytearray ) or not isinstance (op2 , (bytearray , bytes )):
170- return op1 .extend (op2 )
187+ return op1 .extend (* args [ 1 :], ** kwargs )
171188 try :
172189 return _extend_aspect (op1 , op2 )
173190 except Exception as e :
@@ -217,7 +234,9 @@ def build_string_aspect(*args): # type: (List[Any]) -> str
217234
218235
219236def ljust_aspect (orig_function , flag_added_args , * args , ** kwargs ):
220- # type: (Callable, int, Any, Any) -> Union[str, bytes, bytearray]
237+ # type: (Optional[Callable], int, Any, Any) -> Union[str, bytes, bytearray]
238+ if not orig_function :
239+ orig_function = args [0 ].ljust
221240 if not isinstance (orig_function , BuiltinFunctionType ):
222241 if flag_added_args > 0 :
223242 args = args [flag_added_args :]
@@ -252,8 +271,8 @@ def ljust_aspect(orig_function, flag_added_args, *args, **kwargs):
252271
253272
254273def zfill_aspect (orig_function , flag_added_args , * args , ** kwargs ):
255- # type: (Callable, int, Any, Any) -> Any
256- if not isinstance (orig_function , BuiltinFunctionType ):
274+ # type: (Optional[ Callable] , int, Any, Any) -> Any
275+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
257276 if flag_added_args > 0 :
258277 args = args [flag_added_args :]
259278 return orig_function (* args , ** kwargs )
@@ -295,11 +314,14 @@ def zfill_aspect(orig_function, flag_added_args, *args, **kwargs):
295314
296315
297316def format_aspect (
298- orig_function , # type: Callable
317+ orig_function , # type: Optional[ Callable]
299318 flag_added_args , # type: int
300319 * args , # type: Any
301320 ** kwargs , # type: Dict[str, Any]
302321): # type: (...) -> str
322+ if not orig_function :
323+ orig_function = args [0 ].format
324+
303325 if not isinstance (orig_function , BuiltinFunctionType ):
304326 if flag_added_args > 0 :
305327 args = args [flag_added_args :]
@@ -347,8 +369,10 @@ def format_aspect(
347369 return result
348370
349371
350- def format_map_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> str
351- if not isinstance (orig_function , BuiltinFunctionType ):
372+ def format_map_aspect (
373+ orig_function , flag_added_args , * args , ** kwargs
374+ ): # type: (Optional[Callable], int, Any, Any) -> str
375+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
352376 if flag_added_args > 0 :
353377 args = args [flag_added_args :]
354378 return orig_function (* args , ** kwargs )
@@ -494,12 +518,14 @@ def incremental_translation(self, incr_coder, funcode, empty):
494518
495519
496520def decode_aspect (orig_function , flag_added_args , * args , ** kwargs ):
497- if flag_added_args > 0 :
498- self = args [0 ]
499- args = args [flag_added_args :]
500- else :
521+ if orig_function and not flag_added_args :
522+ # This patch is unexpected, so we fallback
523+ # to executing the original function
501524 return orig_function (* args , ** kwargs )
502525
526+ self = args [0 ]
527+ args = args [(flag_added_args or 1 ) :]
528+ # Assume we call decode method of the first argument
503529 result = self .decode (* args , ** kwargs )
504530
505531 if not is_pyobject_tainted (self ) or not isinstance (self , bytes ):
@@ -515,12 +541,14 @@ def decode_aspect(orig_function, flag_added_args, *args, **kwargs):
515541
516542
517543def encode_aspect (orig_function , flag_added_args , * args , ** kwargs ):
518- if flag_added_args > 0 :
519- self = args [0 ]
520- args = args [flag_added_args :]
521- else :
544+ if orig_function and not flag_added_args :
545+ # This patch is unexpected, so we fallback
546+ # to executing the original function
522547 return orig_function (* args , ** kwargs )
523548
549+ self = args [0 ]
550+ args = args [(flag_added_args or 1 ) :]
551+ # Assume we call encode method of the first argument
524552 result = self .encode (* args , ** kwargs )
525553
526554 if not is_pyobject_tainted (self ) or not isinstance (self , str ):
@@ -535,8 +563,10 @@ def encode_aspect(orig_function, flag_added_args, *args, **kwargs):
535563 return result
536564
537565
538- def upper_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
539- if not isinstance (orig_function , BuiltinFunctionType ):
566+ def upper_aspect (
567+ orig_function , flag_added_args , * args , ** kwargs
568+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
569+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
540570 if flag_added_args > 0 :
541571 args = args [flag_added_args :]
542572 return orig_function (* args , ** kwargs )
@@ -553,17 +583,17 @@ def upper_aspect(orig_function, flag_added_args, *args, **kwargs): # type: (Cal
553583 return candidate_text .upper (* args , ** kwargs )
554584
555585
556- def lower_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
557- if not isinstance (orig_function , BuiltinFunctionType ):
586+ def lower_aspect (
587+ orig_function , flag_added_args , * args , ** kwargs
588+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
589+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
558590 if flag_added_args > 0 :
559591 args = args [flag_added_args :]
560592 return orig_function (* args , ** kwargs )
561593
562594 candidate_text = args [0 ]
563595 args = args [flag_added_args :]
564596 if not isinstance (candidate_text , TEXT_TYPES ):
565- if flag_added_args > 0 :
566- args = args [flag_added_args :]
567597 return candidate_text .lower (* args , ** kwargs )
568598
569599 try :
@@ -573,8 +603,10 @@ def lower_aspect(orig_function, flag_added_args, *args, **kwargs): # type: (Cal
573603 return candidate_text .lower (* args , ** kwargs )
574604
575605
576- def swapcase_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
577- if not isinstance (orig_function , BuiltinFunctionType ):
606+ def swapcase_aspect (
607+ orig_function , flag_added_args , * args , ** kwargs
608+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
609+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
578610 if flag_added_args > 0 :
579611 args = args [flag_added_args :]
580612 return orig_function (* args , ** kwargs )
@@ -590,8 +622,10 @@ def swapcase_aspect(orig_function, flag_added_args, *args, **kwargs): # type: (
590622 return candidate_text .swapcase (* args , ** kwargs )
591623
592624
593- def title_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
594- if not isinstance (orig_function , BuiltinFunctionType ):
625+ def title_aspect (
626+ orig_function , flag_added_args , * args , ** kwargs
627+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
628+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
595629 if flag_added_args > 0 :
596630 args = args [flag_added_args :]
597631 return orig_function (* args , ** kwargs )
@@ -607,8 +641,10 @@ def title_aspect(orig_function, flag_added_args, *args, **kwargs): # type: (Cal
607641 return candidate_text .title (* args , ** kwargs )
608642
609643
610- def capitalize_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
611- if not isinstance (orig_function , BuiltinFunctionType ):
644+ def capitalize_aspect (
645+ orig_function , flag_added_args , * args , ** kwargs
646+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
647+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
612648 if flag_added_args > 0 :
613649 args = args [flag_added_args :]
614650 return orig_function (* args , ** kwargs )
@@ -625,16 +661,21 @@ def capitalize_aspect(orig_function, flag_added_args, *args, **kwargs): # type:
625661 return candidate_text .capitalize (* args , ** kwargs )
626662
627663
628- def casefold_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
629- if not isinstance (orig_function , BuiltinFunctionType ):
630- if flag_added_args > 0 :
631- args = args [flag_added_args :]
632- return orig_function (* args , ** kwargs )
664+ def casefold_aspect (
665+ orig_function , flag_added_args , * args , ** kwargs
666+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
667+ if orig_function :
668+ if not isinstance (orig_function , BuiltinFunctionType ):
669+ if flag_added_args > 0 :
670+ args = args [flag_added_args :]
671+ return orig_function (* args , ** kwargs )
672+ else :
673+ orig_function = getattr (args [0 ], "casefold" , None )
633674
634- if orig_function .__qualname__ not in ("str.casefold" , "bytes.casefold" , "bytearray.casefold" ):
675+ if orig_function and orig_function .__qualname__ not in ("str.casefold" , "bytes.casefold" , "bytearray.casefold" ):
635676 if flag_added_args > 0 :
636677 args = args [flag_added_args :]
637- return orig_function (args , ** kwargs )
678+ return orig_function (* args , ** kwargs )
638679
639680 candidate_text = args [0 ]
640681 args = args [flag_added_args :]
@@ -649,8 +690,10 @@ def casefold_aspect(orig_function, flag_added_args, *args, **kwargs): # type: (
649690 return candidate_text .casefold (* args , ** kwargs ) # type: ignore[union-attr]
650691
651692
652- def translate_aspect (orig_function , flag_added_args , * args , ** kwargs ): # type: (Callable, int, Any, Any) -> TEXT_TYPE
653- if not isinstance (orig_function , BuiltinFunctionType ):
693+ def translate_aspect (
694+ orig_function , flag_added_args , * args , ** kwargs
695+ ): # type: (Optional[Callable], int, Any, Any) -> TEXT_TYPE
696+ if orig_function and not isinstance (orig_function , BuiltinFunctionType ):
654697 if flag_added_args > 0 :
655698 args = args [flag_added_args :]
656699 return orig_function (* args , ** kwargs )
0 commit comments