this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "cpython-data.h"
3#include "cpython-func.h"
4
5#include "api-handle.h"
6#include "runtime.h"
7
8namespace py {
9
10static PyObject* typeObjectHandle(LayoutId id) {
11 Runtime* runtime = Thread::current()->runtime();
12 return ApiHandle::borrowedReference(runtime, runtime->typeAt(id));
13}
14
15PY_EXPORT PyObject* PyExc_BaseException_Ptr() {
16 return typeObjectHandle(LayoutId::kBaseException);
17}
18
19PY_EXPORT PyObject* PyExc_Exception_Ptr() {
20 return typeObjectHandle(LayoutId::kException);
21}
22
23PY_EXPORT PyObject* PyExc_StopAsyncIteration_Ptr() {
24 return typeObjectHandle(LayoutId::kStopAsyncIteration);
25}
26
27PY_EXPORT PyObject* PyExc_StopIteration_Ptr() {
28 return typeObjectHandle(LayoutId::kStopIteration);
29}
30
31PY_EXPORT PyObject* PyExc_GeneratorExit_Ptr() {
32 return typeObjectHandle(LayoutId::kGeneratorExit);
33}
34
35PY_EXPORT PyObject* PyExc_ArithmeticError_Ptr() {
36 return typeObjectHandle(LayoutId::kArithmeticError);
37}
38
39PY_EXPORT PyObject* PyExc_LookupError_Ptr() {
40 return typeObjectHandle(LayoutId::kLookupError);
41}
42
43PY_EXPORT PyObject* PyExc_AssertionError_Ptr() {
44 return typeObjectHandle(LayoutId::kAssertionError);
45}
46
47PY_EXPORT PyObject* PyExc_AttributeError_Ptr() {
48 return typeObjectHandle(LayoutId::kAttributeError);
49}
50
51PY_EXPORT PyObject* PyExc_BufferError_Ptr() {
52 return typeObjectHandle(LayoutId::kBufferError);
53}
54
55PY_EXPORT PyObject* PyExc_EOFError_Ptr() {
56 return typeObjectHandle(LayoutId::kEOFError);
57}
58
59PY_EXPORT PyObject* PyExc_FloatingPointError_Ptr() {
60 return typeObjectHandle(LayoutId::kFloatingPointError);
61}
62
63PY_EXPORT PyObject* PyExc_OSError_Ptr() {
64 return typeObjectHandle(LayoutId::kOSError);
65}
66
67PY_EXPORT PyObject* PyExc_ImportError_Ptr() {
68 return typeObjectHandle(LayoutId::kImportError);
69}
70
71PY_EXPORT PyObject* PyExc_ModuleNotFoundError_Ptr() {
72 return typeObjectHandle(LayoutId::kModuleNotFoundError);
73}
74
75PY_EXPORT PyObject* PyExc_IndexError_Ptr() {
76 return typeObjectHandle(LayoutId::kIndexError);
77}
78
79PY_EXPORT PyObject* PyExc_KeyError_Ptr() {
80 return typeObjectHandle(LayoutId::kKeyError);
81}
82
83PY_EXPORT PyObject* PyExc_KeyboardInterrupt_Ptr() {
84 return typeObjectHandle(LayoutId::kKeyboardInterrupt);
85}
86
87PY_EXPORT PyObject* PyExc_MemoryError_Ptr() {
88 return typeObjectHandle(LayoutId::kMemoryError);
89}
90
91PY_EXPORT PyObject* PyExc_NameError_Ptr() {
92 return typeObjectHandle(LayoutId::kNameError);
93}
94
95PY_EXPORT PyObject* PyExc_OverflowError_Ptr() {
96 return typeObjectHandle(LayoutId::kOverflowError);
97}
98
99PY_EXPORT PyObject* PyExc_RuntimeError_Ptr() {
100 return typeObjectHandle(LayoutId::kRuntimeError);
101}
102
103PY_EXPORT PyObject* PyExc_RecursionError_Ptr() {
104 return typeObjectHandle(LayoutId::kRecursionError);
105}
106
107PY_EXPORT PyObject* PyExc_NotImplementedError_Ptr() {
108 return typeObjectHandle(LayoutId::kNotImplementedError);
109}
110
111PY_EXPORT PyObject* PyExc_SyntaxError_Ptr() {
112 return typeObjectHandle(LayoutId::kSyntaxError);
113}
114
115PY_EXPORT PyObject* PyExc_IndentationError_Ptr() {
116 return typeObjectHandle(LayoutId::kIndentationError);
117}
118
119PY_EXPORT PyObject* PyExc_TabError_Ptr() {
120 return typeObjectHandle(LayoutId::kTabError);
121}
122
123PY_EXPORT PyObject* PyExc_ReferenceError_Ptr() {
124 return typeObjectHandle(LayoutId::kReferenceError);
125}
126
127PY_EXPORT PyObject* PyExc_SystemError_Ptr() {
128 return typeObjectHandle(LayoutId::kSystemError);
129}
130
131PY_EXPORT PyObject* PyExc_SystemExit_Ptr() {
132 return typeObjectHandle(LayoutId::kSystemExit);
133}
134
135PY_EXPORT PyObject* PyExc_TypeError_Ptr() {
136 return typeObjectHandle(LayoutId::kTypeError);
137}
138
139PY_EXPORT PyObject* PyExc_UnboundLocalError_Ptr() {
140 return typeObjectHandle(LayoutId::kUnboundLocalError);
141}
142
143PY_EXPORT PyObject* PyExc_UnicodeError_Ptr() {
144 return typeObjectHandle(LayoutId::kUnicodeError);
145}
146
147PY_EXPORT PyObject* PyExc_UnicodeEncodeError_Ptr() {
148 return typeObjectHandle(LayoutId::kUnicodeEncodeError);
149}
150
151PY_EXPORT PyObject* PyExc_UnicodeDecodeError_Ptr() {
152 return typeObjectHandle(LayoutId::kUnicodeDecodeError);
153}
154
155PY_EXPORT PyObject* PyExc_UnicodeTranslateError_Ptr() {
156 return typeObjectHandle(LayoutId::kUnicodeTranslateError);
157}
158
159PY_EXPORT PyObject* PyExc_ValueError_Ptr() {
160 return typeObjectHandle(LayoutId::kValueError);
161}
162
163PY_EXPORT PyObject* PyExc_ZeroDivisionError_Ptr() {
164 return typeObjectHandle(LayoutId::kZeroDivisionError);
165}
166
167PY_EXPORT PyObject* PyExc_BlockingIOError_Ptr() {
168 return typeObjectHandle(LayoutId::kBlockingIOError);
169}
170
171PY_EXPORT PyObject* PyExc_BrokenPipeError_Ptr() {
172 return typeObjectHandle(LayoutId::kBrokenPipeError);
173}
174
175PY_EXPORT PyObject* PyExc_ChildProcessError_Ptr() {
176 return typeObjectHandle(LayoutId::kChildProcessError);
177}
178
179PY_EXPORT PyObject* PyExc_ConnectionError_Ptr() {
180 return typeObjectHandle(LayoutId::kConnectionError);
181}
182
183PY_EXPORT PyObject* PyExc_ConnectionAbortedError_Ptr() {
184 return typeObjectHandle(LayoutId::kConnectionAbortedError);
185}
186
187PY_EXPORT PyObject* PyExc_ConnectionRefusedError_Ptr() {
188 return typeObjectHandle(LayoutId::kConnectionRefusedError);
189}
190
191PY_EXPORT PyObject* PyExc_ConnectionResetError_Ptr() {
192 return typeObjectHandle(LayoutId::kConnectionResetError);
193}
194
195PY_EXPORT PyObject* PyExc_FileExistsError_Ptr() {
196 return typeObjectHandle(LayoutId::kFileExistsError);
197}
198
199PY_EXPORT PyObject* PyExc_FileNotFoundError_Ptr() {
200 return typeObjectHandle(LayoutId::kFileNotFoundError);
201}
202
203PY_EXPORT PyObject* PyExc_InterruptedError_Ptr() {
204 return typeObjectHandle(LayoutId::kInterruptedError);
205}
206
207PY_EXPORT PyObject* PyExc_IsADirectoryError_Ptr() {
208 return typeObjectHandle(LayoutId::kIsADirectoryError);
209}
210
211PY_EXPORT PyObject* PyExc_NotADirectoryError_Ptr() {
212 return typeObjectHandle(LayoutId::kNotADirectoryError);
213}
214
215PY_EXPORT PyObject* PyExc_PermissionError_Ptr() {
216 return typeObjectHandle(LayoutId::kPermissionError);
217}
218
219PY_EXPORT PyObject* PyExc_ProcessLookupError_Ptr() {
220 return typeObjectHandle(LayoutId::kProcessLookupError);
221}
222
223PY_EXPORT PyObject* PyExc_TimeoutError_Ptr() {
224 return typeObjectHandle(LayoutId::kTimeoutError);
225}
226
227PY_EXPORT PyObject* PyExc_Warning_Ptr() {
228 return typeObjectHandle(LayoutId::kWarning);
229}
230
231PY_EXPORT PyObject* PyExc_UserWarning_Ptr() {
232 return typeObjectHandle(LayoutId::kUserWarning);
233}
234
235PY_EXPORT PyObject* PyExc_DeprecationWarning_Ptr() {
236 return typeObjectHandle(LayoutId::kDeprecationWarning);
237}
238
239PY_EXPORT PyObject* PyExc_PendingDeprecationWarning_Ptr() {
240 return typeObjectHandle(LayoutId::kPendingDeprecationWarning);
241}
242
243PY_EXPORT PyObject* PyExc_SyntaxWarning_Ptr() {
244 return typeObjectHandle(LayoutId::kSyntaxWarning);
245}
246
247PY_EXPORT PyObject* PyExc_RuntimeWarning_Ptr() {
248 return typeObjectHandle(LayoutId::kRuntimeWarning);
249}
250
251PY_EXPORT PyObject* PyExc_FutureWarning_Ptr() {
252 return typeObjectHandle(LayoutId::kFutureWarning);
253}
254
255PY_EXPORT PyObject* PyExc_ImportWarning_Ptr() {
256 return typeObjectHandle(LayoutId::kImportWarning);
257}
258
259PY_EXPORT PyObject* PyExc_UnicodeWarning_Ptr() {
260 return typeObjectHandle(LayoutId::kUnicodeWarning);
261}
262
263PY_EXPORT PyObject* PyExc_BytesWarning_Ptr() {
264 return typeObjectHandle(LayoutId::kBytesWarning);
265}
266
267PY_EXPORT PyObject* PyExc_ResourceWarning_Ptr() {
268 return typeObjectHandle(LayoutId::kResourceWarning);
269}
270
271PY_EXPORT int PyExceptionClass_Check_Func(PyObject* obj) {
272 DCHECK(obj != nullptr, "obj should not be null");
273 Thread* thread = Thread::current();
274 Runtime* runtime = thread->runtime();
275 HandleScope scope(thread);
276 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj)));
277 if (!runtime->isInstanceOfType(*object)) {
278 return false;
279 }
280 Type type(&scope, *object);
281 return type.isBaseExceptionSubclass();
282}
283
284PY_EXPORT int PyExceptionInstance_Check_Func(PyObject* obj) {
285 DCHECK(obj != nullptr, "obj should not be null");
286 Thread* thread = Thread::current();
287 HandleScope scope(thread);
288 Object object(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(obj)));
289 return thread->runtime()->isInstanceOfBaseException(*object);
290}
291
292PY_EXPORT void PyException_SetCause(PyObject* self, PyObject* cause) {
293 Thread* thread = Thread::current();
294 HandleScope scope(thread);
295
296 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
297 if (cause == nullptr) {
298 exc.setCause(Unbound::object());
299 return;
300 }
301 ApiHandle* new_cause = ApiHandle::fromPyObject(cause);
302 exc.setCause(ApiHandle::asObject(new_cause));
303 ApiHandle::decref(new_cause);
304}
305
306PY_EXPORT PyObject* PyException_GetCause(PyObject* self) {
307 Thread* thread = Thread::current();
308 HandleScope scope(thread);
309
310 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
311 Object cause(&scope, exc.causeOrUnbound());
312 if (cause.isUnbound()) {
313 return nullptr;
314 }
315 return ApiHandle::newReference(thread->runtime(), *cause);
316}
317
318PY_EXPORT PyObject* PyException_GetContext(PyObject* self) {
319 Thread* thread = Thread::current();
320 HandleScope scope(thread);
321
322 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
323 Object context(&scope, exc.contextOrUnbound());
324 if (context.isUnbound()) {
325 return nullptr;
326 }
327 return ApiHandle::newReference(thread->runtime(), *context);
328}
329
330PY_EXPORT void PyException_SetContext(PyObject* self, PyObject* context) {
331 Thread* thread = Thread::current();
332 HandleScope scope(thread);
333
334 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
335 if (context == nullptr) {
336 exc.setContext(Unbound::object());
337 return;
338 }
339 ApiHandle* new_context = ApiHandle::fromPyObject(context);
340 exc.setContext(ApiHandle::asObject(new_context));
341 ApiHandle::decref(new_context);
342}
343
344PY_EXPORT int PyException_SetTraceback(PyObject* self, PyObject* tb) {
345 Thread* thread = Thread::current();
346 HandleScope scope(thread);
347
348 if (tb == nullptr) {
349 thread->raiseWithFmt(LayoutId::kTypeError,
350 "__traceback__ may not be deleted");
351 return -1;
352 }
353 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
354 Object tb_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(tb)));
355 if (!tb_obj.isNoneType() && !tb_obj.isTraceback()) {
356 thread->raiseWithFmt(LayoutId::kTypeError,
357 "__traceback__ must be a traceback or None");
358 return -1;
359 }
360 exc.setTraceback(*tb_obj);
361 return 0;
362}
363
364PY_EXPORT PyObject* PyException_GetTraceback(PyObject* self) {
365 Thread* thread = Thread::current();
366 HandleScope scope(thread);
367
368 BaseException exc(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(self)));
369 Object tb(&scope, exc.tracebackOrUnbound());
370 if (tb.isUnbound()) return nullptr;
371
372 return ApiHandle::newReference(thread->runtime(), exc.traceback());
373}
374
375PY_EXPORT PyObject* PyUnicodeDecodeError_Create(
376 const char* encoding, const char* object, Py_ssize_t length,
377 Py_ssize_t start, Py_ssize_t end, const char* reason) {
378 Thread* thread = Thread::current();
379 Runtime* runtime = thread->runtime();
380 HandleScope scope(thread);
381 Str encoding_obj(&scope, runtime->newStrFromCStr(encoding));
382 Bytes object_obj(&scope, runtime->newBytesWithAll(View<byte>(
383 reinterpret_cast<const byte*>(object), length)));
384 Int start_obj(&scope, SmallInt::fromWord(start));
385 Int end_obj(&scope, SmallInt::fromWord(end));
386 Str reason_obj(&scope, runtime->newStrFromCStr(reason));
387 Object result(&scope, thread->invokeFunction5(
388 ID(builtins), ID(UnicodeDecodeError), encoding_obj,
389 object_obj, start_obj, end_obj, reason_obj));
390 if (result.isError()) {
391 if (result.isErrorNotFound()) {
392 thread->raiseWithFmt(LayoutId::kRuntimeError,
393 "could not call UnicodeDecodeError()");
394 }
395 return nullptr;
396 }
397 return ApiHandle::newReference(runtime, *result);
398}
399
400PY_EXPORT PyObject* PyUnicodeDecodeError_GetEncoding(PyObject* exc) {
401 PyObject* encoding = PyObject_GetAttrString(exc, "encoding");
402 if (encoding == nullptr) {
403 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
404 "encoding attribute not set");
405 return nullptr;
406 }
407 if (!PyUnicode_Check(encoding)) {
408 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
409 "encoding attribute must be unicode");
410 Py_DECREF(encoding);
411 return nullptr;
412 }
413 return encoding;
414}
415
416PY_EXPORT int PyUnicodeDecodeError_GetEnd(PyObject* exc, Py_ssize_t* end) {
417 Thread* thread = Thread::current();
418 HandleScope scope(thread);
419 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(exc)));
420 Runtime* runtime = thread->runtime();
421 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
422 "exc must be instance of UnicodeError");
423 UnicodeErrorBase exc_err(&scope, *exc_obj);
424 Object object_attr(&scope, exc_err.object());
425 if (!runtime->isInstanceOfBytes(*object_attr)) {
426 thread->raiseWithFmt(LayoutId::kTypeError,
427 "object must be instance of bytes");
428 return -1;
429 }
430 Bytes object(&scope, bytesUnderlying(*object_attr));
431 Object end_attr(&scope, exc_err.end());
432 DCHECK(runtime->isInstanceOfInt(*end_attr), "end must be instance of int");
433 Int end_int(&scope, intUnderlying(*end_attr));
434 *end = end_int.asWord();
435 if (*end < 1) {
436 *end = 1;
437 }
438 word size = object.length();
439 if (*end > size) {
440 *end = size;
441 }
442 return 0;
443}
444
445PY_EXPORT PyObject* PyUnicodeDecodeError_GetObject(PyObject* exc) {
446 PyObject* object = PyObject_GetAttrString(exc, "object");
447 if (object == nullptr) {
448 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
449 "object attribute not set");
450 return nullptr;
451 }
452 if (!PyBytes_Check(object)) {
453 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
454 "object attribute must be bytes");
455 Py_DECREF(object);
456 return nullptr;
457 }
458 return object;
459}
460
461PY_EXPORT PyObject* PyUnicodeDecodeError_GetReason(PyObject* exc) {
462 PyObject* reason = PyObject_GetAttrString(exc, "reason");
463 if (reason == nullptr) {
464 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
465 "reason attribute not set");
466 return nullptr;
467 }
468 if (!PyUnicode_Check(reason)) {
469 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
470 "reason attribute must be unicode");
471 Py_DECREF(reason);
472 return nullptr;
473 }
474 return reason;
475}
476
477PY_EXPORT int PyUnicodeDecodeError_GetStart(PyObject* exc, Py_ssize_t* start) {
478 Thread* thread = Thread::current();
479 HandleScope scope(thread);
480 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(exc)));
481 Runtime* runtime = thread->runtime();
482 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
483 "exc must be instance of UnicodeError");
484 UnicodeErrorBase exc_err(&scope, *exc_obj);
485 Object object_attr(&scope, exc_err.object());
486 if (!runtime->isInstanceOfBytes(*object_attr)) {
487 thread->raiseWithFmt(LayoutId::kTypeError,
488 "object must be instance of bytes");
489 return -1;
490 }
491 Bytes object(&scope, bytesUnderlying(*object_attr));
492 Object start_attr(&scope, exc_err.start());
493 DCHECK(runtime->isInstanceOfInt(*start_attr),
494 "start must be instance of int");
495 Int start_int(&scope, intUnderlying(*start_attr));
496 *start = start_int.asWord();
497 if (*start < 0) {
498 *start = 0;
499 }
500 word size = object.length();
501 if (*start >= size) {
502 *start = size - 1;
503 }
504 return 0;
505}
506
507static int unicodeErrorSetEnd(PyObject* unicode_error, Py_ssize_t end) {
508 Thread* thread = Thread::current();
509 HandleScope scope(thread);
510 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(unicode_error)));
511 Runtime* runtime = thread->runtime();
512 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
513 "exc must be instance of UnicodeError");
514 UnicodeErrorBase exc(&scope, *exc_obj);
515 exc.setEnd(runtime->newInt(end));
516 return 0;
517}
518
519PY_EXPORT int PyUnicodeDecodeError_SetEnd(PyObject* exc, Py_ssize_t end) {
520 return unicodeErrorSetEnd(exc, end);
521}
522
523PY_EXPORT int PyUnicodeDecodeError_SetReason(PyObject* unicode_error,
524 const char* reason) {
525 Thread* thread = Thread::current();
526 HandleScope scope(thread);
527 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(unicode_error)));
528 Runtime* runtime = thread->runtime();
529 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
530 "exc must be instance of UnicodeError");
531 UnicodeErrorBase exc(&scope, *exc_obj);
532 exc.setReason(runtime->newStrFromCStr(reason));
533 return 0;
534}
535
536static int unicodeErrorSetStart(PyObject* unicode_error, Py_ssize_t start) {
537 Thread* thread = Thread::current();
538 HandleScope scope(thread);
539 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(unicode_error)));
540 Runtime* runtime = thread->runtime();
541 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
542 "exc must be instance of UnicodeError");
543 UnicodeErrorBase exc(&scope, *exc_obj);
544 exc.setStart(runtime->newInt(start));
545 return 0;
546}
547
548PY_EXPORT int PyUnicodeDecodeError_SetStart(PyObject* exc, Py_ssize_t start) {
549 return unicodeErrorSetStart(exc, start);
550}
551
552PY_EXPORT PyObject* PyUnicodeEncodeError_GetEncoding(PyObject* exc) {
553 return PyUnicodeDecodeError_GetEncoding(exc);
554}
555
556PY_EXPORT int PyUnicodeEncodeError_GetEnd(PyObject* exc, Py_ssize_t* end) {
557 Thread* thread = Thread::current();
558 HandleScope scope(thread);
559 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(exc)));
560 Runtime* runtime = thread->runtime();
561 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
562 "exc must be instance of UnicodeError");
563 UnicodeErrorBase exc_err(&scope, *exc_obj);
564 Object object_attr(&scope, exc_err.object());
565 if (!runtime->isInstanceOfStr(*object_attr)) {
566 thread->raiseWithFmt(LayoutId::kTypeError,
567 "object must be instance of str");
568 return -1;
569 }
570 Str object(&scope, *object_attr);
571 Object end_attr(&scope, exc_err.end());
572 DCHECK(runtime->isInstanceOfInt(*end_attr), "end must be instance of int");
573 Int end_int(&scope, intUnderlying(*end_attr));
574 *end = end_int.asWord();
575 if (*end < 1) {
576 *end = 1;
577 }
578 word size = object.codePointLength();
579 if (*end > size) {
580 *end = size;
581 }
582 return 0;
583}
584
585PY_EXPORT PyObject* PyUnicodeEncodeError_GetObject(PyObject* exc) {
586 PyObject* object = PyObject_GetAttrString(exc, "object");
587 if (object == nullptr) {
588 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
589 "object attribute not set");
590 return nullptr;
591 }
592 if (!PyUnicode_Check(object)) {
593 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
594 "object attribute must be str");
595 Py_DECREF(object);
596 return nullptr;
597 }
598 return object;
599}
600
601PY_EXPORT PyObject* PyUnicodeEncodeError_GetReason(PyObject* exc) {
602 return PyUnicodeDecodeError_GetReason(exc);
603}
604
605PY_EXPORT int PyUnicodeEncodeError_GetStart(PyObject* exc, Py_ssize_t* start) {
606 Thread* thread = Thread::current();
607 HandleScope scope(thread);
608 Object exc_obj(&scope, ApiHandle::asObject(ApiHandle::fromPyObject(exc)));
609 Runtime* runtime = thread->runtime();
610 DCHECK(runtime->isInstanceOfUnicodeErrorBase(*exc_obj),
611 "exc must be instance of UnicodeError");
612 UnicodeErrorBase exc_err(&scope, *exc_obj);
613 Object object_attr(&scope, exc_err.object());
614 if (!runtime->isInstanceOfStr(*object_attr)) {
615 thread->raiseWithFmt(LayoutId::kTypeError,
616 "object must be instance of str");
617 return -1;
618 }
619 Str object(&scope, *object_attr);
620 Object start_attr(&scope, exc_err.start());
621 DCHECK(runtime->isInstanceOfInt(*start_attr),
622 "start must be instance of int");
623 Int start_int(&scope, intUnderlying(*start_attr));
624 *start = start_int.asWord();
625 if (*start < 0) {
626 *start = 0;
627 }
628 word size = object.codePointLength();
629 if (*start >= size) {
630 *start = size - 1;
631 }
632 return 0;
633}
634
635PY_EXPORT int PyUnicodeEncodeError_SetEnd(PyObject* exc, Py_ssize_t end) {
636 return unicodeErrorSetEnd(exc, end);
637}
638
639PY_EXPORT int PyUnicodeEncodeError_SetReason(PyObject* exc,
640 const char* reason) {
641 return PyUnicodeDecodeError_SetReason(exc, reason);
642}
643
644PY_EXPORT int PyUnicodeEncodeError_SetStart(PyObject* exc, Py_ssize_t start) {
645 return unicodeErrorSetStart(exc, start);
646}
647
648PY_EXPORT int PyUnicodeTranslateError_GetEnd(PyObject* exc, Py_ssize_t* end) {
649 return PyUnicodeEncodeError_GetEnd(exc, end);
650}
651
652PY_EXPORT PyObject* PyUnicodeTranslateError_GetObject(PyObject* exc) {
653 return PyUnicodeEncodeError_GetObject(exc);
654}
655
656PY_EXPORT PyObject* PyUnicodeTranslateError_GetReason(PyObject* exc) {
657 return PyUnicodeEncodeError_GetReason(exc);
658}
659
660PY_EXPORT int PyUnicodeTranslateError_GetStart(PyObject* exc,
661 Py_ssize_t* start) {
662 return PyUnicodeEncodeError_GetStart(exc, start);
663}
664
665PY_EXPORT int PyUnicodeTranslateError_SetEnd(PyObject* exc, Py_ssize_t end) {
666 return unicodeErrorSetEnd(exc, end);
667}
668
669PY_EXPORT int PyUnicodeTranslateError_SetReason(PyObject* exc,
670 const char* reason) {
671 return PyUnicodeEncodeError_SetReason(exc, reason);
672}
673
674PY_EXPORT int PyUnicodeTranslateError_SetStart(PyObject* exc,
675 Py_ssize_t start) {
676 return unicodeErrorSetStart(exc, start);
677}
678
679} // namespace py