Files
Android-pyApi/android_pyapi/java/text.py
T
shuiyu1123 bfe27fdc08 feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
2026-06-24 11:16:16 +00:00

1041 lines
30 KiB
Python

"""
Java text standard library APIs implemented in Python.
java.text package - DateFormat, SimpleDateFormat, DecimalFormat, NumberFormat, etc.
"""
from .._core import Stub
from .lang import RuntimeException
import datetime as _datetime
import time as _time
import re as _re
import math as _py_math
import locale as _locale
from decimal import Decimal as _Decimal
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
__all__ = [
"SimpleDateFormat", "DateFormat", "DateFormatSymbols",
"DecimalFormat", "DecimalFormatSymbols", "NumberFormat",
"ChoiceFormat", "MessageFormat", "FieldPosition", "ParsePosition",
"ParseException", "Normalizer",
"StringCharacterIterator", "CharacterIterator",
"BreakIterator", "Collator", "CollationKey", "RuleBasedCollator",
"Annotation", "AttributedCharacterIterator", "AttributedString",
"Bidi", "Format",
]
# ============================================================
# ParseException
# ============================================================
class ParseException(Exception):
def __init__(self, s, error_offset):
super().__init__(s)
self._error_offset = error_offset
def getErrorOffset(self):
return self._error_offset
# ============================================================
# ParsePosition
# ============================================================
class ParsePosition(Stub):
def __init__(self, index):
super().__init__()
self._index = index
self._error_index = -1
def getIndex(self):
return self._index
def setIndex(self, index):
self._index = index
def getErrorIndex(self):
return self._error_index
def setErrorIndex(self, ei):
self._error_index = ei
# ============================================================
# FieldPosition
# ============================================================
class FieldPosition(Stub):
def __init__(self, field):
super().__init__()
self._field = field
self._begin = 0
self._end = 0
def getField(self):
return self._field
def getBeginIndex(self):
return self._begin
def getEndIndex(self):
return self._end
def setBeginIndex(self, bi):
self._begin = bi
def setEndIndex(self, ei):
self._end = ei
# ============================================================
# Format (base)
# ============================================================
class Format(Stub):
def format(self, obj, to_append_to=None, pos=None):
raise NotImplementedError
def parseObject(self, source, pos=None):
raise NotImplementedError
# ============================================================
# DateFormat
# ============================================================
class DateFormat(Format):
SHORT = 3
MEDIUM = 2
LONG = 1
FULL = 0
DEFAULT = 2
def __init__(self):
super().__init__()
self._calendar = None
self._number_format = None
self._lenient = False
self._timezone = None
@staticmethod
def getDateInstance(style=2, locale=None):
return SimpleDateFormat("yyyy-MM-dd")
@staticmethod
def getTimeInstance(style=2, locale=None):
return SimpleDateFormat("HH:mm:ss")
@staticmethod
def getDateTimeInstance(date_style=2, time_style=2, locale=None):
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
@staticmethod
def getInstance():
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
def format(self, date, to_append_to=None, pos=None):
raise NotImplementedError
def parse(self, source, pos=None):
raise NotImplementedError
def setLenient(self, lenient):
self._lenient = lenient
def isLenient(self):
return self._lenient
def getCalendar(self):
return self._calendar
def setCalendar(self, cal):
self._calendar = cal
def getNumberFormat(self):
return self._number_format
def setNumberFormat(self, nf):
self._number_format = nf
def getTimeZone(self):
return self._timezone
def setTimeZone(self, tz):
self._timezone = tz
# ============================================================
# DateFormatSymbols
# ============================================================
class DateFormatSymbols(Stub):
def __init__(self, locale=None):
super().__init__()
self._months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
]
self._short_months = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
]
self._weekdays = [
"", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday",
]
self._short_weekdays = [
"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
]
self._ampm = ["AM", "PM"]
self._eras = ["BC", "AD"]
self._zone_strings = []
self._local_pattern_chars = "GyMdkHmsSEDFwWahKzZ"
def getMonths(self):
return self._months
def setMonths(self, months):
self._months = months
def getShortMonths(self):
return self._short_months
def setShortMonths(self, months):
self._short_months = months
def getWeekdays(self):
return self._weekdays
def setWeekdays(self, wd):
self._weekdays = wd
def getShortWeekdays(self):
return self._short_weekdays
def setShortWeekdays(self, wd):
self._short_weekdays = wd
def getAmPmStrings(self):
return self._ampm
def setAmPmStrings(self, ap):
self._ampm = ap
def getZoneStrings(self):
return self._zone_strings
def setZoneStrings(self, zs):
self._zone_strings = zs
def getLocalPatternChars(self):
return self._local_pattern_chars
def setLocalPatternChars(self, chars):
self._local_pattern_chars = chars
def getEras(self):
return self._eras
def setEras(self, eras):
self._eras = eras
# ============================================================
# SimpleDateFormat
# ============================================================
_JAVA_TO_PYTHON_FORMAT = {
"yyyy": "%Y", "yy": "%y",
"MM": "%m",
"dd": "%d",
"HH": "%H",
"mm": "%M",
"ss": "%S",
"SSS": "%f",
"a": "%p",
"EEE": "%a", "EEEE": "%A",
"D": "%j",
"zzz": "%Z", "z": "%Z",
"Z": "%z",
}
class SimpleDateFormat(DateFormat):
def __init__(self, pattern, locale=None):
super().__init__()
self._pattern = pattern
self._locale = locale
self._dfs = DateFormatSymbols(locale)
self._lenient = False
def applyPattern(self, pattern):
self._pattern = pattern
def toPattern(self):
return self._pattern
def toLocalizedPattern(self):
return self._pattern
def applyLocalizedPattern(self, pattern):
self._pattern = pattern
def _java_to_py(self, pattern):
py_pattern = pattern
sorted_keys = sorted(_JAVA_TO_PYTHON_FORMAT.keys(), key=lambda x: -len(x))
for java_fmt in sorted_keys:
py_fmt = _JAVA_TO_PYTHON_FORMAT[java_fmt]
py_pattern = py_pattern.replace(java_fmt, py_fmt)
py_pattern = py_pattern.replace("'", "")
return py_pattern
def _to_datetime(self, date):
if isinstance(date, _datetime.datetime):
return date
if isinstance(date, _datetime.date):
return _datetime.datetime.combine(date, _datetime.time())
try:
ts = date.getTime() / 1000.0
return _datetime.datetime.fromtimestamp(ts)
except AttributeError:
return _datetime.datetime.now()
def format(self, date, to_append_to=None, pos=None):
py_pattern = self._java_to_py(self._pattern)
dt = self._to_datetime(date)
result = dt.strftime(py_pattern)
if to_append_to is not None:
sb = str(to_append_to)
idx = len(sb)
to_append_to.append(result)
if pos is not None:
pos.setBeginIndex(idx)
pos.setEndIndex(idx + len(result))
return to_append_to
return result
def parse(self, source, pos=None):
py_pattern = self._java_to_py(self._pattern)
try:
dt = _datetime.datetime.strptime(source, py_pattern)
if pos is not None:
pos.setIndex(len(source))
return dt
except ValueError:
if pos is not None:
pos.setErrorIndex(0)
raise ParseException(f"Unparseable date: {source}", 0)
def setLenient(self, lenient):
self._lenient = lenient
def isLenient(self):
return self._lenient
def setTimeZone(self, tz):
self._timezone = tz
def getTimeZone(self):
return self._timezone
def setCalendar(self, cal):
self._calendar = cal
def getCalendar(self):
return self._calendar
def setNumberFormat(self, nf):
self._number_format = nf
def getNumberFormat(self):
return self._number_format
def getDateFormatSymbols(self):
return self._dfs
def setDateFormatSymbols(self, dfs):
self._dfs = dfs
# ============================================================
# DecimalFormatSymbols
# ============================================================
class DecimalFormatSymbols(Stub):
def __init__(self, locale=None):
super().__init__()
self._decimal_sep = "."
self._grouping_sep = ","
self._pattern_sep = ";"
self._minus_sign = "-"
self._infinity = "\u221e"
self._nan = "NaN"
self._percent = "%"
self._per_mill = "\u2030"
self._zero_digit = "0"
self._digit = "#"
self._exponential_sep = "E"
self._monetary_decimal_sep = "."
self._intl_currency_symbol = "USD"
self._currency = "USD"
def getDecimalSeparator(self): return self._decimal_sep
def setDecimalSeparator(self, c): self._decimal_sep = c
def getGroupingSeparator(self): return self._grouping_sep
def setGroupingSeparator(self, c): self._grouping_sep = c
def getPatternSeparator(self): return self._pattern_sep
def setPatternSeparator(self, c): self._pattern_sep = c
def getMinusSign(self): return self._minus_sign
def setMinusSign(self, c): self._minus_sign = c
def getInfinity(self): return self._infinity
def setInfinity(self, s): self._infinity = s
def getNaN(self): return self._nan
def setNaN(self, s): self._nan = s
def getPercent(self): return self._percent
def setPercent(self, c): self._percent = c
def getPerMill(self): return self._per_mill
def setPerMill(self, c): self._per_mill = c
def getZeroDigit(self): return self._zero_digit
def setZeroDigit(self, c): self._zero_digit = c
def getDigit(self): return self._digit
def setDigit(self, c): self._digit = c
def getExponentialSeparator(self): return self._exponential_sep
def setExponentialSeparator(self, s): self._exponential_sep = s
def getMonetaryDecimalSeparator(self): return self._monetary_decimal_sep
def setMonetaryDecimalSeparator(self, c): self._monetary_decimal_sep = c
def getInternationalCurrencySymbol(self): return self._intl_currency_symbol
def setInternationalCurrencySymbol(self, s): self._intl_currency_symbol = s
def getCurrency(self): return self._currency
def setCurrency(self, c): self._currency = c
# ============================================================
# DecimalFormat
# ============================================================
class NumberFormat(Format):
def __init__(self):
super().__init__()
self._grouping_used = True
self._max_int_digits = 2000000000
self._min_int_digits = 1
self._max_frac_digits = 3
self._min_frac_digits = 0
self._parse_integer_only = False
self._rounding_mode = 4
@staticmethod
def getInstance(locale=None):
return DecimalFormat("#,##0.###")
@staticmethod
def getNumberInstance(locale=None):
return DecimalFormat("#,##0.###")
@staticmethod
def getCurrencyInstance(locale=None):
return DecimalFormat("#,##0.00")
@staticmethod
def getPercentInstance(locale=None):
return DecimalFormat("#,##0%")
@staticmethod
def getIntegerInstance(locale=None):
nf = DecimalFormat("#,##0")
nf.setMaximumFractionDigits(0)
return nf
@staticmethod
def getCompactNumberInstance(locale=None, style=None):
return DecimalFormat("#,##0")
def format(self, number, to_append_to=None, pos=None):
raise NotImplementedError
def parse(self, source, pos=None):
raise NotImplementedError
def isGroupingUsed(self): return self._grouping_used
def setGroupingUsed(self, v): self._grouping_used = v
def getMaximumIntegerDigits(self): return self._max_int_digits
def setMaximumIntegerDigits(self, v): self._max_int_digits = v
def getMinimumIntegerDigits(self): return self._min_int_digits
def setMinimumIntegerDigits(self, v): self._min_int_digits = v
def getMaximumFractionDigits(self): return self._max_frac_digits
def setMaximumFractionDigits(self, v): self._max_frac_digits = v
def getMinimumFractionDigits(self): return self._min_frac_digits
def setMinimumFractionDigits(self, v): self._min_frac_digits = v
def setParseIntegerOnly(self, v): self._parse_integer_only = v
def isParseIntegerOnly(self): return self._parse_integer_only
def setRoundingMode(self, v): self._rounding_mode = v
def getRoundingMode(self): return self._rounding_mode
def getCurrency(self): return "USD"
def setCurrency(self, c): pass
@staticmethod
def getAvailableLocales():
return list(_locale.locale_alias.keys())
# ============================================================
# ChoiceFormat
# ============================================================
class ChoiceFormat(NumberFormat):
def __init__(self, formats=None, limits=None):
super().__init__()
self._formats = formats if formats is not None else []
self._limits = limits if limits is not None else []
def format(self, number, to_append_to=None, pos=None):
val = float(number)
idx = 0
for i, lim in enumerate(self._limits):
if val >= lim:
idx = i
result = str(self._formats[idx]) if idx < len(self._formats) else ""
if to_append_to is not None:
sb = str(to_append_to)
idx2 = len(sb)
to_append_to.append(result)
if pos is not None:
pos.setBeginIndex(idx2)
pos.setEndIndex(idx2 + len(result))
return to_append_to
return result
def parse(self, source, pos=None):
raise NotImplementedError
@staticmethod
def nextDouble(d, upwards=True):
if upwards:
return d + _py_math.ulp(d)
return d - _py_math.ulp(d)
@staticmethod
def previousDouble(d):
return ChoiceFormat.nextDouble(d, False)
def getLimits(self):
return self._limits
def getFormats(self):
return self._formats
# ============================================================
# MessageFormat
# ============================================================
# NumberFormat
# ============================================================
# ============================================================
# DecimalFormat
# ============================================================
class DecimalFormat(NumberFormat):
def __init__(self, pattern=None, symbols=None):
super().__init__()
self._pattern = pattern or "#,##0.###"
self._symbols = symbols or DecimalFormatSymbols()
self._decimal_sep_always = False
self._grouping_size = 3
self._grouping_used = True
self._max_int_digits = 2000000000
self._min_int_digits = 1
self._max_frac_digits = 2000000000
self._min_frac_digits = 0
self._neg_prefix = "-"
self._neg_suffix = ""
self._pos_prefix = ""
self._pos_suffix = ""
self._multiplier = 1
self._rounding_mode = 4
self._parse_bigdecimal = False
def applyPattern(self, pattern):
self._pattern = pattern
def toPattern(self):
return self._pattern
def toLocalizedPattern(self):
return self._pattern
def applyLocalizedPattern(self, pattern):
self._pattern = pattern
def format(self, number, to_append_to=None, pos=None):
if isinstance(number, (int, float)):
val = number * self._multiplier
elif isinstance(number, _Decimal):
val = float(str(number)) * self._multiplier
else:
val = float(str(number)) * self._multiplier
if self._grouping_used and self._grouping_size > 0:
result = f"{val:,.{self._max_frac_digits}f}"
else:
fmt = "{{:.{}f}}".format(self._max_frac_digits)
result = fmt.format(val)
prefix = self._pos_prefix if val >= 0 else self._neg_prefix
suffix = self._pos_suffix if val >= 0 else self._neg_suffix
result = prefix + result + suffix
if to_append_to is not None:
sb = str(to_append_to)
idx = len(sb)
to_append_to.append(result)
if pos is not None:
pos.setBeginIndex(idx)
pos.setEndIndex(idx + len(result))
return to_append_to
return result
def parse(self, source, pos=None):
text = source.strip()
try:
val = float(text)
if pos is not None:
pos.setIndex(len(source))
if self._parse_bigdecimal:
return _Decimal(str(val))
return val
except ValueError:
if pos is not None:
pos.setErrorIndex(0)
raise Exception(f"Unparseable: {source}")
def setDecimalSeparatorAlwaysShown(self, v): self._decimal_sep_always = v
def getDecimalSeparatorAlwaysShown(self): return self._decimal_sep_always
def setGroupingSize(self, v): self._grouping_size = v
def getGroupingSize(self): return self._grouping_size
def setGroupingUsed(self, v): self._grouping_used = v
def isGroupingUsed(self): return self._grouping_used
def setMaximumIntegerDigits(self, v): self._max_int_digits = v
def getMaximumIntegerDigits(self): return self._max_int_digits
def setMinimumIntegerDigits(self, v): self._min_int_digits = v
def getMinimumIntegerDigits(self): return self._min_int_digits
def setMaximumFractionDigits(self, v): self._max_frac_digits = v
def getMaximumFractionDigits(self): return self._max_frac_digits
def setMinimumFractionDigits(self, v): self._min_frac_digits = v
def getMinimumFractionDigits(self): return self._min_frac_digits
def setNegativePrefix(self, v): self._neg_prefix = v
def getNegativePrefix(self): return self._neg_prefix
def setNegativeSuffix(self, v): self._neg_suffix = v
def getNegativeSuffix(self): return self._neg_suffix
def setPositivePrefix(self, v): self._pos_prefix = v
def getPositivePrefix(self): return self._pos_prefix
def setPositiveSuffix(self, v): self._pos_suffix = v
def getPositiveSuffix(self): return self._pos_suffix
def setDecimalFormatSymbols(self, v): self._symbols = v
def getDecimalFormatSymbols(self): return self._symbols
def setParseBigDecimal(self, v): self._parse_bigdecimal = v
def isParseBigDecimal(self): return self._parse_bigdecimal
def setMultiplier(self, v): self._multiplier = v
def getMultiplier(self): return self._multiplier
def setRoundingMode(self, v): self._rounding_mode = v
def getRoundingMode(self): return self._rounding_mode
# ============================================================
# MessageFormat
# ============================================================
_MSG_PATTERN_RE = _re.compile(r"\{(\d+)(?:,(\w+)(?:,(.+))?)?\}")
class MessageFormat(Format):
def __init__(self, pattern, locale=None):
super().__init__()
self._pattern = pattern
self._locale = locale
self._formats = {}
def applyPattern(self, pattern):
self._pattern = pattern
def toPattern(self):
return self._pattern
def _format_impl(self, objects):
def replacer(m):
idx = int(m.group(1))
if idx < len(objects):
return str(objects[idx])
return m.group(0)
return _MSG_PATTERN_RE.sub(replacer, self._pattern)
def format(self, objects, to_append_to=None, pos=None):
result = self._format_impl(objects)
if to_append_to is not None:
sb = str(to_append_to)
idx = len(sb)
to_append_to.append(result)
if pos is not None:
pos.setBeginIndex(idx)
pos.setEndIndex(idx + len(result))
return to_append_to
return result
@staticmethod
def format_static(pattern, *args):
mf = MessageFormat(pattern)
return mf.format(args)
def parse(self, source, pos=None):
parts = _MSG_PATTERN_RE.split(self._pattern)
result = []
idx = 0
for i, part in enumerate(parts):
if i % 2 == 0:
if not source[idx:].startswith(part):
if pos is not None:
pos.setErrorIndex(idx)
return result
idx += len(part)
else:
arg_idx = int(part)
remaining = source[idx:]
next_part = parts[i + 1] if i + 1 < len(parts) else ""
end = remaining.find(next_part) if next_part else len(remaining)
if end < 0:
end = len(remaining)
result.append(remaining[:end])
idx += end
if pos is not None:
pos.setIndex(idx)
return result
def setLocale(self, locale):
self._locale = locale
def getLocale(self):
return self._locale
def setFormats(self, formats):
self._formats = formats
def getFormats(self):
return self._formats
def setFormat(self, idx, fmt):
self._formats[idx] = fmt
def getFormat(self, idx):
return self._formats.get(idx)
# ============================================================
# CharacterIterator
# ============================================================
class CharacterIterator(Stub):
DONE = chr(0xFFFF)
def first(self):
raise NotImplementedError
def last(self):
raise NotImplementedError
def current(self):
raise NotImplementedError
def next(self):
raise NotImplementedError
def previous(self):
raise NotImplementedError
def setIndex(self, position):
raise NotImplementedError
def getBeginIndex(self):
raise NotImplementedError
def getEndIndex(self):
raise NotImplementedError
def getIndex(self):
raise NotImplementedError
def clone(self):
raise NotImplementedError
# ============================================================
# StringCharacterIterator
# ============================================================
class StringCharacterIterator(CharacterIterator):
def __init__(self, text):
super().__init__()
self._text = text
self._begin = 0
self._end = len(text)
self._pos = 0
def first(self):
self._pos = self._begin
return self.current()
def last(self):
self._pos = self._end - 1 if self._end > self._begin else self._begin
return self.current()
def current(self):
if self._pos >= self._begin and self._pos < self._end:
return self._text[self._pos]
return CharacterIterator.DONE
def next(self):
self._pos += 1
if self._pos >= self._end:
self._pos = self._end
return CharacterIterator.DONE
return self._text[self._pos]
def previous(self):
self._pos -= 1
if self._pos < self._begin:
self._pos = self._begin
return CharacterIterator.DONE
return self._text[self._pos]
def setIndex(self, pos):
self._pos = max(self._begin, min(pos, self._end))
return self.current()
def getBeginIndex(self):
return self._begin
def getEndIndex(self):
return self._end
def getIndex(self):
return self._pos
def clone(self):
return StringCharacterIterator(self._text)
# ============================================================
# BreakIterator
# ============================================================
class BreakIterator(Stub):
DONE = -1
@staticmethod
def getWordInstance(locale=None):
return BreakIterator()
@staticmethod
def getLineInstance(locale=None):
return BreakIterator()
@staticmethod
def getCharacterInstance(locale=None):
return BreakIterator()
@staticmethod
def getSentenceInstance(locale=None):
return BreakIterator()
def setText(self, text):
self._text = text
def first(self):
return 0
def last(self):
return len(self._text) if hasattr(self, "_text") else 0
def next(self, n=1):
return BreakIterator.DONE
def previous(self):
return BreakIterator.DONE
def current(self):
return 0
def following(self, offset):
return BreakIterator.DONE
def preceding(self, offset):
return BreakIterator.DONE
def isBoundary(self, offset):
return True
# ============================================================
# Collator / CollationKey / RuleBasedCollator
# ============================================================
class CollationKey(Stub):
def __init__(self, source, key):
super().__init__()
self._source = source
self._key = key
def compareTo(self, other):
if isinstance(other, CollationKey):
return (self._key > other._key) - (self._key < other._key)
return -1
def getSourceString(self):
return self._source
def toByteArray(self):
return self._key.encode("utf-8")
class Collator(Stub):
PRIMARY = 0
SECONDARY = 1
TERTIARY = 2
IDENTICAL = 3
NO_DECOMPOSITION = 0
CANONICAL_DECOMPOSITION = 1
FULL_DECOMPOSITION = 2
@staticmethod
def getInstance(locale=None):
return RuleBasedCollator()
def compare(self, source, target):
return (source > target) - (source < target)
def getCollationKey(self, source):
return CollationKey(source, source)
def setStrength(self, strength):
self._strength = strength
def getStrength(self):
return getattr(self, "_strength", Collator.TERTIARY)
def setDecomposition(self, decomposition):
self._decomposition = decomposition
def getDecomposition(self):
return getattr(self, "_decomposition", Collator.NO_DECOMPOSITION)
class RuleBasedCollator(Collator):
def __init__(self, rules=None):
super().__init__()
self._rules = rules or ""
# ============================================================
# Normalizer
# ============================================================
class Normalizer(Stub):
class Form(Stub):
NFC = "NFC"
NFD = "NFD"
NFKC = "NFKC"
NFKD = "NFKD"
@staticmethod
def normalize(src, form):
import unicodedata
form_map = {
Normalizer.Form.NFC: "NFC",
Normalizer.Form.NFD: "NFD",
Normalizer.Form.NFKC: "NFKC",
Normalizer.Form.NFKD: "NFKD",
}
return unicodedata.normalize(form_map.get(form, "NFC"), src)
@staticmethod
def isNormalized(src, form):
return Normalizer.normalize(src, form) == src
# ============================================================
# Annotation / AttributedCharacterIterator / AttributedString
# ============================================================
class Annotation(Stub):
def __init__(self, value):
super().__init__()
self._value = value
def getValue(self):
return self._value
def toString(self):
return str(self._value)
class AttributedCharacterIterator(CharacterIterator):
pass
class AttributedString(Stub):
def __init__(self, text, attributes=None):
super().__init__()
self._text = text
def getIterator(self):
return StringCharacterIterator(self._text)
# ============================================================
# Bidi
# ============================================================
class Bidi(Stub):
DIRECTION_LEFT_TO_RIGHT = 0
DIRECTION_RIGHT_TO_LEFT = 1
DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2
DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1
def __init__(self, text, flags=0):
super().__init__()
self._text = text
self._base_level = 0 if flags >= 0 else 1
def isLeftToRight(self):
return self._base_level == 0
def isRightToLeft(self):
return self._base_level == 1
def getLength(self):
return len(self._text)
def getLevelAt(self, offset):
return self._base_level
def getRunCount(self):
return 1
def getRunLevel(self, run):
return self._base_level
def getRunLimit(self, run):
return len(self._text)
def getRunStart(self, run):
return 0
def requiresBidi(self, text):
for ch in text:
if ord(ch) > 0x590:
return True
return False
@staticmethod
def reorderVisually(levels, objects, index, count):
pass
@staticmethod
def baseIsLeftToRight():
return True