1 #define PY_SSIZE_T_CLEAN 2 #include "Python.h" 3 #include "bytes_methods.h" 4 5 PyDoc_STRVAR_shared(_Py_isspace__doc__, 6 "B.isspace() -> bool\n\ 7 \n\ 8 Return True if all characters in B are whitespace\n\ 9 and there is at least one character in B, False otherwise."); 10 11 PyObject* 12 _Py_bytes_isspace(const char *cptr, Py_ssize_t len) 13 { 14 const unsigned char *p 15 = (unsigned char *) cptr; 16 const unsigned char *e; 17 18 /* Shortcut for single character strings */ 19 if (len == 1 && Py_ISSPACE(*p)) 20 Py_RETURN_TRUE; 21 22 /* Special case for empty strings */ 23 if (len == 0) 24 Py_RETURN_FALSE; 25 26 e = p + len; 27 for (; p < e; p++) { 28 if (!Py_ISSPACE(*p)) 29 Py_RETURN_FALSE; 30 } 31 Py_RETURN_TRUE; 32 } 33 34 35 PyDoc_STRVAR_shared(_Py_isalpha__doc__, 36 "B.isalpha() -> bool\n\ 37 \n\ 38 Return True if all characters in B are alphabetic\n\ 39 and there is at least one character in B, False otherwise."); 40 41 PyObject* 42 _Py_bytes_isalpha(const char *cptr, Py_ssize_t len) 43 { 44 const unsigned char *p 45 = (unsigned char *) cptr; 46 const unsigned char *e; 47 48 /* Shortcut for single character strings */ 49 if (len == 1 && Py_ISALPHA(*p)) 50 Py_RETURN_TRUE; 51 52 /* Special case for empty strings */ 53 if (len == 0) 54 Py_RETURN_FALSE; 55 56 e = p + len; 57 for (; p < e; p++) { 58 if (!Py_ISALPHA(*p)) 59 Py_RETURN_FALSE; 60 } 61 Py_RETURN_TRUE; 62 } 63 64 65 PyDoc_STRVAR_shared(_Py_isalnum__doc__, 66 "B.isalnum() -> bool\n\ 67 \n\ 68 Return True if all characters in B are alphanumeric\n\ 69 and there is at least one character in B, False otherwise."); 70 71 PyObject* 72 _Py_bytes_isalnum(const char *cptr, Py_ssize_t len) 73 { 74 const unsigned char *p 75 = (unsigned char *) cptr; 76 const unsigned char *e; 77 78 /* Shortcut for single character strings */ 79 if (len == 1 && Py_ISALNUM(*p)) 80 Py_RETURN_TRUE; 81 82 /* Special case for empty strings */ 83 if (len == 0) 84 Py_RETURN_FALSE; 85 86 e = p + len; 87 for (; p < e; p++) { 88 if (!Py_ISALNUM(*p)) 89 Py_RETURN_FALSE; 90 } 91 Py_RETURN_TRUE; 92 } 93 94 95 PyDoc_STRVAR_shared(_Py_isdigit__doc__, 96 "B.isdigit() -> bool\n\ 97 \n\ 98 Return True if all characters in B are digits\n\ 99 and there is at least one character in B, False otherwise."); 100 101 PyObject* 102 _Py_bytes_isdigit(const char *cptr, Py_ssize_t len) 103 { 104 const unsigned char *p 105 = (unsigned char *) cptr; 106 const unsigned char *e; 107 108 /* Shortcut for single character strings */ 109 if (len == 1 && Py_ISDIGIT(*p)) 110 Py_RETURN_TRUE; 111 112 /* Special case for empty strings */ 113 if (len == 0) 114 Py_RETURN_FALSE; 115 116 e = p + len; 117 for (; p < e; p++) { 118 if (!Py_ISDIGIT(*p)) 119 Py_RETURN_FALSE; 120 } 121 Py_RETURN_TRUE; 122 } 123 124 125 PyDoc_STRVAR_shared(_Py_islower__doc__, 126 "B.islower() -> bool\n\ 127 \n\ 128 Return True if all cased characters in B are lowercase and there is\n\ 129 at least one cased character in B, False otherwise."); 130 131 PyObject* 132 _Py_bytes_islower(const char *cptr, Py_ssize_t len) 133 { 134 const unsigned char *p 135 = (unsigned char *) cptr; 136 const unsigned char *e; 137 int cased; 138 139 /* Shortcut for single character strings */ 140 if (len == 1) 141 return PyBool_FromLong(Py_ISLOWER(*p)); 142 143 /* Special case for empty strings */ 144 if (len == 0) 145 Py_RETURN_FALSE; 146 147 e = p + len; 148 cased = 0; 149 for (; p < e; p++) { 150 if (Py_ISUPPER(*p)) 151 Py_RETURN_FALSE; 152 else if (!cased && Py_ISLOWER(*p)) 153 cased = 1; 154 } 155 return PyBool_FromLong(cased); 156 } 157 158 159 PyDoc_STRVAR_shared(_Py_isupper__doc__, 160 "B.isupper() -> bool\n\ 161 \n\ 162 Return True if all cased characters in B are uppercase and there is\n\ 163 at least one cased character in B, False otherwise."); 164 165 PyObject* 166 _Py_bytes_isupper(const char *cptr, Py_ssize_t len) 167 { 168 const unsigned char *p 169 = (unsigned char *) cptr; 170 const unsigned char *e; 171 int cased; 172 173 /* Shortcut for single character strings */ 174 if (len == 1) 175 return PyBool_FromLong(Py_ISUPPER(*p)); 176 177 /* Special case for empty strings */ 178 if (len == 0) 179 Py_RETURN_FALSE; 180 181 e = p + len; 182 cased = 0; 183 for (; p < e; p++) { 184 if (Py_ISLOWER(*p)) 185 Py_RETURN_FALSE; 186 else if (!cased && Py_ISUPPER(*p)) 187 cased = 1; 188 } 189 return PyBool_FromLong(cased); 190 } 191 192 193 PyDoc_STRVAR_shared(_Py_istitle__doc__, 194 "B.istitle() -> bool\n\ 195 \n\ 196 Return True if B is a titlecased string and there is at least one\n\ 197 character in B, i.e. uppercase characters may only follow uncased\n\ 198 characters and lowercase characters only cased ones. Return False\n\ 199 otherwise."); 200 201 PyObject* 202 _Py_bytes_istitle(const char *cptr, Py_ssize_t len) 203 { 204 const unsigned char *p 205 = (unsigned char *) cptr; 206 const unsigned char *e; 207 int cased, previous_is_cased; 208 209 /* Shortcut for single character strings */ 210 if (len == 1) 211 return PyBool_FromLong(Py_ISUPPER(*p)); 212 213 /* Special case for empty strings */ 214 if (len == 0) 215 Py_RETURN_FALSE; 216 217 e = p + len; 218 cased = 0; 219 previous_is_cased = 0; 220 for (; p < e; p++) { 221 const unsigned char ch = *p; 222 223 if (Py_ISUPPER(ch)) { 224 if (previous_is_cased) 225 Py_RETURN_FALSE; 226 previous_is_cased = 1; 227 cased = 1; 228 } 229 else if (Py_ISLOWER(ch)) { 230 if (!previous_is_cased) 231 Py_RETURN_FALSE; 232 previous_is_cased = 1; 233 cased = 1; 234 } 235 else 236 previous_is_cased = 0; 237 } 238 return PyBool_FromLong(cased); 239 } 240 241 242 PyDoc_STRVAR_shared(_Py_lower__doc__, 243 "B.lower() -> copy of B\n\ 244 \n\ 245 Return a copy of B with all ASCII characters converted to lowercase."); 246 247 void 248 _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len) 249 { 250 Py_ssize_t i; 251 252 for (i = 0; i < len; i++) { 253 result[i] = Py_TOLOWER((unsigned char) cptr[i]); 254 } 255 } 256 257 258 PyDoc_STRVAR_shared(_Py_upper__doc__, 259 "B.upper() -> copy of B\n\ 260 \n\ 261 Return a copy of B with all ASCII characters converted to uppercase."); 262 263 void 264 _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len) 265 { 266 Py_ssize_t i; 267 268 for (i = 0; i < len; i++) { 269 result[i] = Py_TOUPPER((unsigned char) cptr[i]); 270 } 271 } 272 273 274 PyDoc_STRVAR_shared(_Py_title__doc__, 275 "B.title() -> copy of B\n\ 276 \n\ 277 Return a titlecased version of B, i.e. ASCII words start with uppercase\n\ 278 characters, all remaining cased characters have lowercase."); 279 280 void 281 _Py_bytes_title(char *result, const char *s, Py_ssize_t len) 282 { 283 Py_ssize_t i; 284 int previous_is_cased = 0; 285 286 for (i = 0; i < len; i++) { 287 int c = Py_CHARMASK(*s++); 288 if (Py_ISLOWER(c)) { 289 if (!previous_is_cased) 290 c = Py_TOUPPER(c); 291 previous_is_cased = 1; 292 } else if (Py_ISUPPER(c)) { 293 if (previous_is_cased) 294 c = Py_TOLOWER(c); 295 previous_is_cased = 1; 296 } else 297 previous_is_cased = 0; 298 *result++ = c; 299 } 300 } 301 302 303 PyDoc_STRVAR_shared(_Py_capitalize__doc__, 304 "B.capitalize() -> copy of B\n\ 305 \n\ 306 Return a copy of B with only its first character capitalized (ASCII)\n\ 307 and the rest lower-cased."); 308 309 void 310 _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len) 311 { 312 Py_ssize_t i; 313 314 if (0 < len) { 315 int c = Py_CHARMASK(*s++); 316 if (Py_ISLOWER(c)) 317 *result = Py_TOUPPER(c); 318 else 319 *result = c; 320 result++; 321 } 322 for (i = 1; i < len; i++) { 323 int c = Py_CHARMASK(*s++); 324 if (Py_ISUPPER(c)) 325 *result = Py_TOLOWER(c); 326 else 327 *result = c; 328 result++; 329 } 330 } 331 332 333 PyDoc_STRVAR_shared(_Py_swapcase__doc__, 334 "B.swapcase() -> copy of B\n\ 335 \n\ 336 Return a copy of B with uppercase ASCII characters converted\n\ 337 to lowercase ASCII and vice versa."); 338 339 void 340 _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len) 341 { 342 Py_ssize_t i; 343 344 for (i = 0; i < len; i++) { 345 int c = Py_CHARMASK(*s++); 346 if (Py_ISLOWER(c)) { 347 *result = Py_TOUPPER(c); 348 } 349 else if (Py_ISUPPER(c)) { 350 *result = Py_TOLOWER(c); 351 } 352 else 353 *result = c; 354 result++; 355 } 356 } 357 358 359 PyDoc_STRVAR_shared(_Py_maketrans__doc__, 360 "B.maketrans(frm, to) -> translation table\n\ 361 \n\ 362 Return a translation table (a bytes object of length 256) suitable\n\ 363 for use in the bytes or bytearray translate method where each byte\n\ 364 in frm is mapped to the byte at the same position in to.\n\ 365 The bytes objects frm and to must be of the same length."); 366 367 PyObject * 368 _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) 369 { 370 PyObject *res = NULL; 371 Py_ssize_t i; 372 char *p; 373 374 if (frm->len != to->len) { 375 PyErr_Format(PyExc_ValueError, 376 "maketrans arguments must have same length"); 377 return NULL; 378 } 379 res = PyBytes_FromStringAndSize(NULL, 256); 380 if (!res) 381 return NULL; 382 p = PyBytes_AS_STRING(res); 383 for (i = 0; i < 256; i++) 384 p[i] = (char) i; 385 for (i = 0; i < frm->len; i++) { 386 p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i]; 387 } 388 389 return res; 390 } 391 392 #define FASTSEARCH fastsearch 393 #define STRINGLIB(F) stringlib_##F 394 #define STRINGLIB_CHAR char 395 #define STRINGLIB_SIZEOF_CHAR 1 396 397 #include "stringlib/fastsearch.h" 398 #include "stringlib/count.h" 399 #include "stringlib/find.h" 400 401 /* 402 Wraps stringlib_parse_args_finds() and additionally checks whether the 403 first argument is an integer in range(0, 256). 404 405 If this is the case, writes the integer value to the byte parameter 406 and sets subobj to NULL. Otherwise, sets the first argument to subobj 407 and doesn't touch byte. The other parameters are similar to those of 408 stringlib_parse_args_finds(). 409 */ 410 411 Py_LOCAL_INLINE(int) 412 parse_args_finds_byte(const char *function_name, PyObject *args, 413 PyObject **subobj, char *byte, 414 Py_ssize_t *start, Py_ssize_t *end) 415 { 416 PyObject *tmp_subobj; 417 Py_ssize_t ival; 418 PyObject *err; 419 420 if(!stringlib_parse_args_finds(function_name, args, &tmp_subobj, 421 start, end)) 422 return 0; 423 424 if (!PyNumber_Check(tmp_subobj)) { 425 *subobj = tmp_subobj; 426 return 1; 427 } 428 429 ival = PyNumber_AsSsize_t(tmp_subobj, PyExc_OverflowError); 430 if (ival == -1) { 431 err = PyErr_Occurred(); 432 if (err && !PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) { 433 PyErr_Clear(); 434 *subobj = tmp_subobj; 435 return 1; 436 } 437 } 438 439 if (ival < 0 || ival > 255) { 440 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); 441 return 0; 442 } 443 444 *subobj = NULL; 445 *byte = (char)ival; 446 return 1; 447 } 448 449 /* helper macro to fixup start/end slice values */ 450 #define ADJUST_INDICES(start, end, len) \ 451 if (end > len) \ 452 end = len; \ 453 else if (end < 0) { \ 454 end += len; \ 455 if (end < 0) \ 456 end = 0; \ 457 } \ 458 if (start < 0) { \ 459 start += len; \ 460 if (start < 0) \ 461 start = 0; \ 462 } 463 464 Py_LOCAL_INLINE(Py_ssize_t) 465 find_internal(const char *str, Py_ssize_t len, 466 const char *function_name, PyObject *args, int dir) 467 { 468 PyObject *subobj; 469 char byte; 470 Py_buffer subbuf; 471 const char *sub; 472 Py_ssize_t sub_len; 473 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; 474 Py_ssize_t res; 475 476 if (!parse_args_finds_byte(function_name, args, 477 &subobj, &byte, &start, &end)) 478 return -2; 479 480 if (subobj) { 481 if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) 482 return -2; 483 484 sub = subbuf.buf; 485 sub_len = subbuf.len; 486 } 487 else { 488 sub = &byte; 489 sub_len = 1; 490 } 491 492 ADJUST_INDICES(start, end, len); 493 if (end - start < sub_len) 494 res = -1; 495 else if (sub_len == 1) { 496 if (dir > 0) 497 res = stringlib_find_char( 498 str + start, end - start, 499 *sub); 500 else 501 res = stringlib_rfind_char( 502 str + start, end - start, 503 *sub); 504 if (res >= 0) 505 res += start; 506 } 507 else { 508 if (dir > 0) 509 res = stringlib_find_slice( 510 str, len, 511 sub, sub_len, start, end); 512 else 513 res = stringlib_rfind_slice( 514 str, len, 515 sub, sub_len, start, end); 516 } 517 518 if (subobj) 519 PyBuffer_Release(&subbuf); 520 521 return res; 522 } 523 524 PyDoc_STRVAR_shared(_Py_find__doc__, 525 "B.find(sub[, start[, end]]) -> int\n\ 526 \n\ 527 Return the lowest index in B where subsection sub is found,\n\ 528 such that sub is contained within B[start,end]. Optional\n\ 529 arguments start and end are interpreted as in slice notation.\n\ 530 \n\ 531 Return -1 on failure."); 532 533 PyObject * 534 _Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args) 535 { 536 Py_ssize_t result = find_internal(str, len, "find", args, +1); 537 if (result == -2) 538 return NULL; 539 return PyLong_FromSsize_t(result); 540 } 541 542 PyDoc_STRVAR_shared(_Py_index__doc__, 543 "B.index(sub[, start[, end]]) -> int\n\ 544 \n\ 545 Like B.find() but raise ValueError when the subsection is not found."); 546 547 PyObject * 548 _Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args) 549 { 550 Py_ssize_t result = find_internal(str, len, "index", args, +1); 551 if (result == -2) 552 return NULL; 553 if (result == -1) { 554 PyErr_SetString(PyExc_ValueError, 555 "subsection not found"); 556 return NULL; 557 } 558 return PyLong_FromSsize_t(result); 559 } 560 561 PyDoc_STRVAR_shared(_Py_rfind__doc__, 562 "B.rfind(sub[, start[, end]]) -> int\n\ 563 \n\ 564 Return the highest index in B where subsection sub is found,\n\ 565 such that sub is contained within B[start,end]. Optional\n\ 566 arguments start and end are interpreted as in slice notation.\n\ 567 \n\ 568 Return -1 on failure."); 569 570 PyObject * 571 _Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args) 572 { 573 Py_ssize_t result = find_internal(str, len, "rfind", args, -1); 574 if (result == -2) 575 return NULL; 576 return PyLong_FromSsize_t(result); 577 } 578 579 PyDoc_STRVAR_shared(_Py_rindex__doc__, 580 "B.rindex(sub[, start[, end]]) -> int\n\ 581 \n\ 582 Like B.rfind() but raise ValueError when the subsection is not found."); 583 584 PyObject * 585 _Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args) 586 { 587 Py_ssize_t result = find_internal(str, len, "rindex", args, -1); 588 if (result == -2) 589 return NULL; 590 if (result == -1) { 591 PyErr_SetString(PyExc_ValueError, 592 "subsection not found"); 593 return NULL; 594 } 595 return PyLong_FromSsize_t(result); 596 } 597 598 PyDoc_STRVAR_shared(_Py_count__doc__, 599 "B.count(sub[, start[, end]]) -> int\n\ 600 \n\ 601 Return the number of non-overlapping occurrences of subsection sub in\n\ 602 bytes B[start:end]. Optional arguments start and end are interpreted\n\ 603 as in slice notation."); 604 605 PyObject * 606 _Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args) 607 { 608 PyObject *sub_obj; 609 const char *sub; 610 Py_ssize_t sub_len; 611 char byte; 612 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; 613 614 Py_buffer vsub; 615 PyObject *count_obj; 616 617 if (!parse_args_finds_byte("count", args, 618 &sub_obj, &byte, &start, &end)) 619 return NULL; 620 621 if (sub_obj) { 622 if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) 623 return NULL; 624 625 sub = vsub.buf; 626 sub_len = vsub.len; 627 } 628 else { 629 sub = &byte; 630 sub_len = 1; 631 } 632 633 ADJUST_INDICES(start, end, len); 634 635 count_obj = PyLong_FromSsize_t( 636 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) 637 ); 638 639 if (sub_obj) 640 PyBuffer_Release(&vsub); 641 642 return count_obj; 643 } 644 645 int 646 _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg) 647 { 648 Py_ssize_t ival = PyNumber_AsSsize_t(arg, NULL); 649 if (ival == -1 && PyErr_Occurred()) { 650 Py_buffer varg; 651 Py_ssize_t pos; 652 PyErr_Clear(); 653 if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) 654 return -1; 655 pos = stringlib_find(str, len, 656 varg.buf, varg.len, 0); 657 PyBuffer_Release(&varg); 658 return pos >= 0; 659 } 660 if (ival < 0 || ival >= 256) { 661 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); 662 return -1; 663 } 664 665 return memchr(str, (int) ival, len) != NULL; 666 } 667 668 669 /* Matches the end (direction >= 0) or start (direction < 0) of the buffer 670 * against substr, using the start and end arguments. Returns 671 * -1 on error, 0 if not found and 1 if found. 672 */ 673 static int 674 tailmatch(const char *str, Py_ssize_t len, PyObject *substr, 675 Py_ssize_t start, Py_ssize_t end, int direction) 676 { 677 Py_buffer sub_view = {NULL, NULL}; 678 const char *sub; 679 Py_ssize_t slen; 680 681 if (PyBytes_Check(substr)) { 682 sub = PyBytes_AS_STRING(substr); 683 slen = PyBytes_GET_SIZE(substr); 684 } 685 else { 686 if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0) 687 return -1; 688 sub = sub_view.buf; 689 slen = sub_view.len; 690 } 691 692 ADJUST_INDICES(start, end, len); 693 694 if (direction < 0) { 695 /* startswith */ 696 if (start + slen > len) 697 goto notfound; 698 } else { 699 /* endswith */ 700 if (end - start < slen || start > len) 701 goto notfound; 702 703 if (end - slen > start) 704 start = end - slen; 705 } 706 if (end - start < slen) 707 goto notfound; 708 if (memcmp(str + start, sub, slen) != 0) 709 goto notfound; 710 711 PyBuffer_Release(&sub_view); 712 return 1; 713 714 notfound: 715 PyBuffer_Release(&sub_view); 716 return 0; 717 } 718 719 static PyObject * 720 _Py_bytes_tailmatch(const char *str, Py_ssize_t len, 721 const char *function_name, PyObject *args, 722 int direction) 723 { 724 Py_ssize_t start = 0; 725 Py_ssize_t end = PY_SSIZE_T_MAX; 726 PyObject *subobj; 727 int result; 728 729 if (!stringlib_parse_args_finds(function_name, args, &subobj, &start, &end)) 730 return NULL; 731 if (PyTuple_Check(subobj)) { 732 Py_ssize_t i; 733 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { 734 result = tailmatch(str, len, PyTuple_GET_ITEM(subobj, i), 735 start, end, direction); 736 if (result == -1) 737 return NULL; 738 else if (result) { 739 Py_RETURN_TRUE; 740 } 741 } 742 Py_RETURN_FALSE; 743 } 744 result = tailmatch(str, len, subobj, start, end, direction); 745 if (result == -1) { 746 if (PyErr_ExceptionMatches(PyExc_TypeError)) 747 PyErr_Format(PyExc_TypeError, 748 "%s first arg must be bytes or a tuple of bytes, " 749 "not %s", 750 function_name, Py_TYPE(subobj)->tp_name); 751 return NULL; 752 } 753 else 754 return PyBool_FromLong(result); 755 } 756 757 PyDoc_STRVAR_shared(_Py_startswith__doc__, 758 "B.startswith(prefix[, start[, end]]) -> bool\n\ 759 \n\ 760 Return True if B starts with the specified prefix, False otherwise.\n\ 761 With optional start, test B beginning at that position.\n\ 762 With optional end, stop comparing B at that position.\n\ 763 prefix can also be a tuple of bytes to try."); 764 765 PyObject * 766 _Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args) 767 { 768 return _Py_bytes_tailmatch(str, len, "startswith", args, -1); 769 } 770 771 PyDoc_STRVAR_shared(_Py_endswith__doc__, 772 "B.endswith(suffix[, start[, end]]) -> bool\n\ 773 \n\ 774 Return True if B ends with the specified suffix, False otherwise.\n\ 775 With optional start, test B beginning at that position.\n\ 776 With optional end, stop comparing B at that position.\n\ 777 suffix can also be a tuple of bytes to try."); 778 779 PyObject * 780 _Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args) 781 { 782 return _Py_bytes_tailmatch(str, len, "endswith", args, +1); 783 } 784 785 PyDoc_STRVAR_shared(_Py_expandtabs__doc__, 786 "B.expandtabs(tabsize=8) -> copy of B\n\ 787 \n\ 788 Return a copy of B where all tab characters are expanded using spaces.\n\ 789 If tabsize is not given, a tab size of 8 characters is assumed."); 790 791 PyDoc_STRVAR_shared(_Py_ljust__doc__, 792 "B.ljust(width[, fillchar]) -> copy of B\n" 793 "\n" 794 "Return B left justified in a string of length width. Padding is\n" 795 "done using the specified fill character (default is a space)."); 796 797 PyDoc_STRVAR_shared(_Py_rjust__doc__, 798 "B.rjust(width[, fillchar]) -> copy of B\n" 799 "\n" 800 "Return B right justified in a string of length width. Padding is\n" 801 "done using the specified fill character (default is a space)"); 802 803 PyDoc_STRVAR_shared(_Py_center__doc__, 804 "B.center(width[, fillchar]) -> copy of B\n" 805 "\n" 806 "Return B centered in a string of length width. Padding is\n" 807 "done using the specified fill character (default is a space)."); 808 809 PyDoc_STRVAR_shared(_Py_zfill__doc__, 810 "B.zfill(width) -> copy of B\n" 811 "\n" 812 "Pad a numeric string B with zeros on the left, to fill a field\n" 813 "of the specified width. B is never truncated."); 814 815