@@ -274,7 +274,7 @@ def reduce(function, sequence, initial=_initial_missing):
274
274
################################################################################
275
275
276
276
277
- class PlaceholderType :
277
+ class __PlaceholderTypeBase :
278
278
"""The type of the Placeholder singleton.
279
279
280
280
Used as a placeholder for partial arguments.
@@ -296,7 +296,7 @@ def __reduce__(self):
296
296
return 'Placeholder'
297
297
298
298
299
- Placeholder = PlaceholderType ()
299
+ Placeholder = type ( ' PlaceholderType' , ( __PlaceholderTypeBase ,), {}) ()
300
300
301
301
302
302
# Purely functional, no descriptor behaviour
@@ -311,19 +311,20 @@ class partial:
311
311
def __new__ (cls , func , / , * args , ** keywords ):
312
312
if not callable (func ):
313
313
raise TypeError ("the first argument must be callable" )
314
- np = 0
315
314
if args :
316
315
if args [- 1 ] is Placeholder :
317
316
raise TypeError ("trailing Placeholders are not allowed" )
318
- np = args [:- 1 ].count (Placeholder )
317
+ np = args .count (Placeholder )
318
+ else :
319
+ np = 0
319
320
if isinstance (func , partial ):
320
321
pargs = func .args
321
322
pnp = func .placeholder_count
322
323
# merge args with args of `func` which is `partial`
323
324
if pnp and args :
324
325
all_args = list (pargs )
325
326
nargs = len (args )
326
- pos , j = 0 , 0
327
+ pos = j = 0
327
328
end = nargs if nargs < pnp else pnp
328
329
while j < end :
329
330
pos = all_args .index (Placeholder , pos )
@@ -351,19 +352,20 @@ def __call__(self, /, *args, **keywords):
351
352
np = self .placeholder_count
352
353
p_args = self .args
353
354
if np :
354
- if len (args ) < np :
355
+ n = len (args )
356
+ if n < np :
355
357
raise TypeError (
356
358
"missing positional arguments "
357
359
"in 'partial' call; expected "
358
- f"at least { np } , got { len ( args ) } " )
360
+ f"at least { np } , got { n } " )
359
361
p_args = list (p_args )
360
- j , pos = 0 , 0
362
+ pos = j = 0
361
363
while j < np :
362
364
pos = p_args .index (Placeholder , pos )
363
365
p_args [pos ] = args [j ]
364
- j += 1
365
366
pos += 1
366
- args = args [j :]
367
+ j += 1
368
+ args = args [np :] if n > np else ()
367
369
keywords = {** self .keywords , ** keywords }
368
370
return self .func (* p_args , * args , ** keywords )
369
371
@@ -409,7 +411,7 @@ def __setstate__(self, state):
409
411
self .placeholder_count = placeholder_count
410
412
411
413
try :
412
- from _functools import partial , PlaceholderType , Placeholder
414
+ from _functools import partial , Placeholder
413
415
except ImportError :
414
416
pass
415
417
0 commit comments