rapyer 1.2.0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rapyer/__init__.py +2 -0
- rapyer/base.py +71 -55
- rapyer/context.py +0 -3
- rapyer/scripts/constants.py +3 -0
- rapyer/scripts/loader.py +4 -3
- rapyer/scripts/registry.py +31 -8
- rapyer/types/dct.py +13 -2
- {rapyer-1.2.0.dist-info → rapyer-1.2.1.dist-info}/METADATA +1 -1
- {rapyer-1.2.0.dist-info → rapyer-1.2.1.dist-info}/RECORD +10 -10
- {rapyer-1.2.0.dist-info → rapyer-1.2.1.dist-info}/WHEEL +1 -1
rapyer/__init__.py
CHANGED
|
@@ -7,6 +7,7 @@ from rapyer.base import (
|
|
|
7
7
|
find_redis_models,
|
|
8
8
|
ainsert,
|
|
9
9
|
alock_from_key,
|
|
10
|
+
apipeline,
|
|
10
11
|
)
|
|
11
12
|
from rapyer.init import init_rapyer, teardown_rapyer
|
|
12
13
|
|
|
@@ -19,4 +20,5 @@ __all__ = [
|
|
|
19
20
|
"find_redis_models",
|
|
20
21
|
"ainsert",
|
|
21
22
|
"alock_from_key",
|
|
23
|
+
"apipeline",
|
|
22
24
|
]
|
rapyer/base.py
CHANGED
|
@@ -18,12 +18,10 @@ from pydantic import (
|
|
|
18
18
|
ValidationError,
|
|
19
19
|
)
|
|
20
20
|
from pydantic_core.core_schema import FieldSerializationInfo, ValidationInfo
|
|
21
|
-
from redis.
|
|
22
|
-
from redis.commands.search.query import Query
|
|
23
|
-
from redis.exceptions import NoScriptError, ResponseError
|
|
21
|
+
from redis.client import Pipeline
|
|
24
22
|
|
|
25
23
|
from rapyer.config import RedisConfig
|
|
26
|
-
from rapyer.context import _context_var
|
|
24
|
+
from rapyer.context import _context_var
|
|
27
25
|
from rapyer.errors.base import (
|
|
28
26
|
KeyNotFound,
|
|
29
27
|
PersistentNoScriptError,
|
|
@@ -36,7 +34,7 @@ from rapyer.fields.index import IndexAnnotation
|
|
|
36
34
|
from rapyer.fields.key import KeyAnnotation
|
|
37
35
|
from rapyer.fields.safe_load import SafeLoadAnnotation
|
|
38
36
|
from rapyer.links import REDIS_SUPPORTED_LINK
|
|
39
|
-
from rapyer.scripts import
|
|
37
|
+
from rapyer.scripts import registry as scripts_registry
|
|
40
38
|
from rapyer.types.base import RedisType, REDIS_DUMP_FLAG_NAME, FAILED_FIELDS_KEY
|
|
41
39
|
from rapyer.types.convert import RedisConverter
|
|
42
40
|
from rapyer.typing_support import Self, Unpack
|
|
@@ -56,6 +54,9 @@ from rapyer.utils.redis import (
|
|
|
56
54
|
acquire_lock,
|
|
57
55
|
update_keys_in_pipeline,
|
|
58
56
|
)
|
|
57
|
+
from redis.commands.search.index_definition import IndexDefinition, IndexType
|
|
58
|
+
from redis.commands.search.query import Query
|
|
59
|
+
from redis.exceptions import NoScriptError, ResponseError
|
|
59
60
|
|
|
60
61
|
logger = logging.getLogger("rapyer")
|
|
61
62
|
|
|
@@ -150,6 +151,10 @@ class AtomicRedisModel(BaseModel):
|
|
|
150
151
|
field_path = self.field_path
|
|
151
152
|
return f"${field_path}" if field_path else "$"
|
|
152
153
|
|
|
154
|
+
@property
|
|
155
|
+
def client(self):
|
|
156
|
+
return _context_var.get() or self.Meta.redis
|
|
157
|
+
|
|
153
158
|
@classmethod
|
|
154
159
|
def should_refresh(cls):
|
|
155
160
|
return cls.Meta.refresh_ttl and cls.Meta.ttl is not None
|
|
@@ -312,10 +317,10 @@ class AtomicRedisModel(BaseModel):
|
|
|
312
317
|
|
|
313
318
|
async def asave(self) -> Self:
|
|
314
319
|
model_dump = self.redis_dump()
|
|
315
|
-
await self.
|
|
320
|
+
await self.client.json().set(self.key, self.json_path, model_dump)
|
|
316
321
|
if self.Meta.ttl is not None:
|
|
317
322
|
nx = not self.Meta.refresh_ttl
|
|
318
|
-
await self.
|
|
323
|
+
await self.client.expire(self.key, self.Meta.ttl, nx=nx)
|
|
319
324
|
return self
|
|
320
325
|
|
|
321
326
|
def redis_dump(self):
|
|
@@ -533,7 +538,9 @@ class AtomicRedisModel(BaseModel):
|
|
|
533
538
|
async def apipeline(
|
|
534
539
|
self, ignore_redis_error: bool = False
|
|
535
540
|
) -> AbstractAsyncContextManager[Self]:
|
|
536
|
-
async with
|
|
541
|
+
async with apipeline(
|
|
542
|
+
ignore_redis_error=ignore_redis_error, _meta=self.Meta
|
|
543
|
+
) as pipe:
|
|
537
544
|
try:
|
|
538
545
|
redis_model = await self.__class__.aget(self.key)
|
|
539
546
|
unset_fields = {
|
|
@@ -545,57 +552,13 @@ class AtomicRedisModel(BaseModel):
|
|
|
545
552
|
redis_model = self
|
|
546
553
|
else:
|
|
547
554
|
raise
|
|
548
|
-
_context_var.set(pipe)
|
|
549
|
-
_context_xx_pipe.set(ignore_redis_error)
|
|
550
555
|
yield redis_model
|
|
551
|
-
commands_backup = list(pipe.command_stack)
|
|
552
|
-
noscript_on_first_attempt = False
|
|
553
|
-
noscript_on_retry = False
|
|
554
|
-
|
|
555
|
-
try:
|
|
556
|
-
if self.should_refresh():
|
|
557
|
-
pipe.expire(self.key, self.Meta.ttl)
|
|
558
|
-
await pipe.execute()
|
|
559
|
-
except NoScriptError:
|
|
560
|
-
noscript_on_first_attempt = True
|
|
561
|
-
except ResponseError as exc:
|
|
562
|
-
if ignore_redis_error:
|
|
563
|
-
logger.warning(
|
|
564
|
-
"Swallowed ResponseError during pipeline.execute() with "
|
|
565
|
-
"ignore_redis_error=True for key %r: %s",
|
|
566
|
-
getattr(self, "key", None),
|
|
567
|
-
exc,
|
|
568
|
-
)
|
|
569
|
-
else:
|
|
570
|
-
raise
|
|
571
|
-
|
|
572
|
-
if noscript_on_first_attempt:
|
|
573
|
-
await handle_noscript_error(self.Meta.redis)
|
|
574
|
-
evalsha_commands = [
|
|
575
|
-
(args, options)
|
|
576
|
-
for args, options in commands_backup
|
|
577
|
-
if args[0] == "EVALSHA"
|
|
578
|
-
]
|
|
579
|
-
# Retry execute the pipeline actions
|
|
580
|
-
async with self.Meta.redis.pipeline(transaction=True) as retry_pipe:
|
|
581
|
-
for args, options in evalsha_commands:
|
|
582
|
-
retry_pipe.execute_command(*args, **options)
|
|
583
|
-
try:
|
|
584
|
-
await retry_pipe.execute()
|
|
585
|
-
except NoScriptError:
|
|
586
|
-
noscript_on_retry = True
|
|
587
|
-
|
|
588
|
-
if noscript_on_retry:
|
|
589
|
-
raise PersistentNoScriptError(
|
|
590
|
-
"NOSCRIPT error persisted after re-registering scripts. "
|
|
591
|
-
"This indicates a server-side problem with Redis."
|
|
592
|
-
)
|
|
593
556
|
|
|
594
|
-
|
|
595
|
-
|
|
557
|
+
if self.should_refresh():
|
|
558
|
+
pipe.expire(self.key, self.Meta.ttl)
|
|
596
559
|
|
|
597
560
|
def __setattr__(self, name: str, value: Any) -> None:
|
|
598
|
-
if name not in self.
|
|
561
|
+
if name not in self.__class__.model_fields or value is None:
|
|
599
562
|
super().__setattr__(name, value)
|
|
600
563
|
return
|
|
601
564
|
|
|
@@ -723,3 +686,56 @@ async def alock_from_key(
|
|
|
723
686
|
yield redis_model
|
|
724
687
|
if save_at_end and redis_model is not None:
|
|
725
688
|
await redis_model.asave()
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
@contextlib.asynccontextmanager
|
|
692
|
+
async def apipeline(
|
|
693
|
+
ignore_redis_error: bool = False, _meta: RedisConfig = None
|
|
694
|
+
) -> AbstractAsyncContextManager[Pipeline]:
|
|
695
|
+
_meta = _meta or AtomicRedisModel.Meta
|
|
696
|
+
redis = _meta.redis
|
|
697
|
+
async with redis.pipeline(transaction=True) as pipe:
|
|
698
|
+
pipe_prev = _context_var.set(pipe)
|
|
699
|
+
try:
|
|
700
|
+
yield pipe
|
|
701
|
+
commands_backup = list(pipe.command_stack)
|
|
702
|
+
noscript_on_first_attempt = False
|
|
703
|
+
noscript_on_retry = False
|
|
704
|
+
|
|
705
|
+
try:
|
|
706
|
+
await pipe.execute()
|
|
707
|
+
except NoScriptError:
|
|
708
|
+
noscript_on_first_attempt = True
|
|
709
|
+
except ResponseError as exc:
|
|
710
|
+
if ignore_redis_error:
|
|
711
|
+
logger.warning(
|
|
712
|
+
"Swallowed ResponseError during pipeline.execute() with "
|
|
713
|
+
"ignore_redis_error=True: %s",
|
|
714
|
+
exc,
|
|
715
|
+
)
|
|
716
|
+
else:
|
|
717
|
+
raise
|
|
718
|
+
|
|
719
|
+
if noscript_on_first_attempt:
|
|
720
|
+
await scripts_registry.handle_noscript_error(redis, _meta)
|
|
721
|
+
evalsha_commands = [
|
|
722
|
+
(args, options)
|
|
723
|
+
for args, options in commands_backup
|
|
724
|
+
if args[0] == "EVALSHA"
|
|
725
|
+
]
|
|
726
|
+
# Retry execute the pipeline actions
|
|
727
|
+
async with redis.pipeline(transaction=True) as retry_pipe:
|
|
728
|
+
for args, options in evalsha_commands:
|
|
729
|
+
retry_pipe.execute_command(*args, **options)
|
|
730
|
+
try:
|
|
731
|
+
await retry_pipe.execute()
|
|
732
|
+
except NoScriptError:
|
|
733
|
+
noscript_on_retry = True
|
|
734
|
+
|
|
735
|
+
if noscript_on_retry:
|
|
736
|
+
raise PersistentNoScriptError(
|
|
737
|
+
"NOSCRIPT error persisted after re-registering scripts. "
|
|
738
|
+
"This indicates a server-side problem with Redis."
|
|
739
|
+
)
|
|
740
|
+
finally:
|
|
741
|
+
_context_var.reset(pipe_prev)
|
rapyer/context.py
CHANGED
rapyer/scripts/constants.py
CHANGED
rapyer/scripts/loader.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from functools import lru_cache
|
|
2
2
|
from importlib import resources
|
|
3
3
|
|
|
4
|
+
from rapyer.scripts.constants import FAKEREDIS_VARIANT, REDIS_VARIANT
|
|
4
5
|
|
|
5
6
|
VARIANTS = {
|
|
6
|
-
|
|
7
|
+
REDIS_VARIANT: {
|
|
7
8
|
"EXTRACT_ARRAY": "local arr = cjson.decode(arr_json)[1]",
|
|
8
9
|
"EXTRACT_VALUE": "local value = tonumber(cjson.decode(current_json)[1])",
|
|
9
10
|
"EXTRACT_STR": "local value = cjson.decode(current_json)[1]",
|
|
@@ -19,7 +20,7 @@ else
|
|
|
19
20
|
extracted = parsed
|
|
20
21
|
end""",
|
|
21
22
|
},
|
|
22
|
-
|
|
23
|
+
FAKEREDIS_VARIANT: {
|
|
23
24
|
"EXTRACT_ARRAY": "local arr = cjson.decode(arr_json)",
|
|
24
25
|
"EXTRACT_VALUE": "local value = tonumber(cjson.decode(current_json)[1])",
|
|
25
26
|
"EXTRACT_STR": "local value = cjson.decode(current_json)[1]",
|
|
@@ -45,7 +46,7 @@ def _load_template(category: str, name: str) -> str:
|
|
|
45
46
|
return resources.files(package).joinpath(filename).read_text()
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
def load_script(category: str, name: str, variant: str =
|
|
49
|
+
def load_script(category: str, name: str, variant: str = REDIS_VARIANT) -> str:
|
|
49
50
|
template = _load_template(category, name)
|
|
50
51
|
replacements = VARIANTS[variant]
|
|
51
52
|
result = template
|
rapyer/scripts/registry.py
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
from
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from rapyer.errors import PersistentNoScriptError, ScriptsNotInitializedError
|
|
2
4
|
from rapyer.scripts.constants import (
|
|
3
5
|
DATETIME_ADD_SCRIPT_NAME,
|
|
4
6
|
DICT_POP_SCRIPT_NAME,
|
|
5
7
|
DICT_POPITEM_SCRIPT_NAME,
|
|
8
|
+
FAKEREDIS_VARIANT,
|
|
6
9
|
NUM_FLOORDIV_SCRIPT_NAME,
|
|
7
10
|
NUM_MOD_SCRIPT_NAME,
|
|
8
11
|
NUM_MUL_SCRIPT_NAME,
|
|
9
12
|
NUM_POW_FLOAT_SCRIPT_NAME,
|
|
10
13
|
NUM_POW_SCRIPT_NAME,
|
|
11
14
|
NUM_TRUEDIV_SCRIPT_NAME,
|
|
15
|
+
REDIS_VARIANT,
|
|
12
16
|
REMOVE_RANGE_SCRIPT_NAME,
|
|
13
17
|
STR_APPEND_SCRIPT_NAME,
|
|
14
18
|
STR_MUL_SCRIPT_NAME,
|
|
15
19
|
)
|
|
16
20
|
from rapyer.scripts.loader import load_script
|
|
21
|
+
from redis.exceptions import NoScriptError
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from rapyer.config import RedisConfig
|
|
17
25
|
|
|
18
26
|
SCRIPT_REGISTRY: list[tuple[str, str, str]] = [
|
|
19
27
|
("list", "remove_range", REMOVE_RANGE_SCRIPT_NAME),
|
|
@@ -41,15 +49,15 @@ def _build_scripts(variant: str) -> dict[str, str]:
|
|
|
41
49
|
|
|
42
50
|
|
|
43
51
|
def get_scripts() -> dict[str, str]:
|
|
44
|
-
return _build_scripts(
|
|
52
|
+
return _build_scripts(REDIS_VARIANT)
|
|
45
53
|
|
|
46
54
|
|
|
47
55
|
def get_scripts_fakeredis() -> dict[str, str]:
|
|
48
|
-
return _build_scripts(
|
|
56
|
+
return _build_scripts(FAKEREDIS_VARIANT)
|
|
49
57
|
|
|
50
58
|
|
|
51
59
|
async def register_scripts(redis_client, is_fakeredis: bool = False) -> None:
|
|
52
|
-
variant =
|
|
60
|
+
variant = FAKEREDIS_VARIANT if is_fakeredis else REDIS_VARIANT
|
|
53
61
|
scripts = _build_scripts(variant)
|
|
54
62
|
for name, script_text in scripts.items():
|
|
55
63
|
sha = await redis_client.script_load(script_text)
|
|
@@ -70,10 +78,25 @@ def run_sha(pipeline, script_name: str, keys: int, *args):
|
|
|
70
78
|
pipeline.evalsha(sha, keys, *args)
|
|
71
79
|
|
|
72
80
|
|
|
73
|
-
async def arun_sha(
|
|
81
|
+
async def arun_sha(
|
|
82
|
+
client, redis_config: "RedisConfig", script_name: str, keys: int, *args
|
|
83
|
+
):
|
|
84
|
+
sha = get_script(script_name)
|
|
85
|
+
try:
|
|
86
|
+
return await client.evalsha(sha, keys, *args)
|
|
87
|
+
except NoScriptError:
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
await handle_noscript_error(client, redis_config)
|
|
74
91
|
sha = get_script(script_name)
|
|
75
|
-
|
|
92
|
+
try:
|
|
93
|
+
return await client.evalsha(sha, keys, *args)
|
|
94
|
+
except NoScriptError as e:
|
|
95
|
+
raise PersistentNoScriptError(
|
|
96
|
+
"NOSCRIPT error persisted after re-registering scripts. "
|
|
97
|
+
"This indicates a server-side problem with Redis."
|
|
98
|
+
) from e
|
|
76
99
|
|
|
77
100
|
|
|
78
|
-
async def handle_noscript_error(redis_client
|
|
79
|
-
await register_scripts(redis_client)
|
|
101
|
+
async def handle_noscript_error(redis_client, redis_config: "RedisConfig"):
|
|
102
|
+
await register_scripts(redis_client, is_fakeredis=redis_config.is_fake_redis)
|
rapyer/types/dct.py
CHANGED
|
@@ -106,7 +106,13 @@ class RedisDict(dict[str, T], GenericRedisType, Generic[T]):
|
|
|
106
106
|
|
|
107
107
|
async def apop(self, key, default=None):
|
|
108
108
|
result = await arun_sha(
|
|
109
|
-
self.client,
|
|
109
|
+
self.client,
|
|
110
|
+
self.Meta,
|
|
111
|
+
DICT_POP_SCRIPT_NAME,
|
|
112
|
+
1,
|
|
113
|
+
self.key,
|
|
114
|
+
self.json_path,
|
|
115
|
+
key,
|
|
110
116
|
)
|
|
111
117
|
super().pop(key, None)
|
|
112
118
|
await self.refresh_ttl_if_needed()
|
|
@@ -120,7 +126,12 @@ class RedisDict(dict[str, T], GenericRedisType, Generic[T]):
|
|
|
120
126
|
|
|
121
127
|
async def apopitem(self):
|
|
122
128
|
result = await arun_sha(
|
|
123
|
-
self.client,
|
|
129
|
+
self.client,
|
|
130
|
+
self.Meta,
|
|
131
|
+
DICT_POPITEM_SCRIPT_NAME,
|
|
132
|
+
1,
|
|
133
|
+
self.key,
|
|
134
|
+
self.json_path,
|
|
124
135
|
)
|
|
125
136
|
await self.refresh_ttl_if_needed()
|
|
126
137
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rapyer
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Pydantic models with Redis as the backend
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: redis,redis-json,pydantic,pydantic-v2,orm,database,async,nosql,cache,key-value,data-modeling,python,backend,storage,serialization,validation
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
rapyer/__init__.py,sha256=
|
|
2
|
-
rapyer/base.py,sha256=
|
|
1
|
+
rapyer/__init__.py,sha256=PEFZI3eMHz-1ojcHEczcHKWAwloF5UYIibsvNg7O6a4,447
|
|
2
|
+
rapyer/base.py,sha256=Q5SdwByj7cCGsKAVsITEfvp9ayp7b-KwTJzRR8Qd7fU,27196
|
|
3
3
|
rapyer/config.py,sha256=Js1FGfyKfS16eOTgsPEhFfi1yTM_UkR8v2z_Vv6C3Bo,978
|
|
4
|
-
rapyer/context.py,sha256=
|
|
4
|
+
rapyer/context.py,sha256=MyyjpcIe2y8wUpiPNv-uYA2iDJyTuL_YxIueByle2kg,247
|
|
5
5
|
rapyer/errors/__init__.py,sha256=P-DIYe85wySkCpuyWufwF7zOOOL8NUiMaHZROsciG1M,530
|
|
6
6
|
rapyer/errors/base.py,sha256=PBTEbR0Y8rEhQXuWHAhoHnSxvoZ5nDfUW3Th2KOdb9M,804
|
|
7
7
|
rapyer/fields/__init__.py,sha256=KyFUM5v0kdM2chITE5cH-L-IL_LRhWDXGbezhXgtEF0,157
|
|
@@ -12,8 +12,8 @@ rapyer/fields/safe_load.py,sha256=xS3PwOe9K2D7az-ctNV798cTSIb7bcviWHQ1kL1tbBo,59
|
|
|
12
12
|
rapyer/init.py,sha256=R6xncUnBeq07gtM_iWqH4SHLquH7MNQgTbVbC6xIA6U,2133
|
|
13
13
|
rapyer/links.py,sha256=A0usszwvwXI7FqwTEYquGYrqyNQqT4HUWhqmLteGXWU,121
|
|
14
14
|
rapyer/scripts/__init__.py,sha256=FvTJvulDxVnVqc8JK4GmHXeS-lMis4_cudaQYe7_VKg,1130
|
|
15
|
-
rapyer/scripts/constants.py,sha256=
|
|
16
|
-
rapyer/scripts/loader.py,sha256=
|
|
15
|
+
rapyer/scripts/constants.py,sha256=5PdpyNb94SRgzcskto41gG4Za35UxNJ8Nd0LtoC8RIg,509
|
|
16
|
+
rapyer/scripts/loader.py,sha256=m5dy3L_FbyFR5oor2JqG-dOLp3JnZDYg5Zhd9YJFrdY,1915
|
|
17
17
|
rapyer/scripts/lua/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
rapyer/scripts/lua/datetime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
rapyer/scripts/lua/datetime/add.lua,sha256=wMhBkAr9KoDRtDR0qG0ofA8BENO1Ykr7f437kVLIUww,1536
|
|
@@ -32,13 +32,13 @@ rapyer/scripts/lua/numeric/truediv.lua,sha256=lQv6YuPb7YHsg50x7b_zDuQ3S1Oa3oeydO
|
|
|
32
32
|
rapyer/scripts/lua/string/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
33
|
rapyer/scripts/lua/string/append.lua,sha256=JfSt21qCQzIMB_0dLmN58s9MFBDaOkiA8dBSBDO77bU,310
|
|
34
34
|
rapyer/scripts/lua/string/mul.lua,sha256=rABORn6gxXobY44S1JYeLnLPeTZu26otemB0s6tBfx8,328
|
|
35
|
-
rapyer/scripts/registry.py,sha256=
|
|
35
|
+
rapyer/scripts/registry.py,sha256=uPHw3SMYqkyWAAo_j9RqZtHl54jPTwSGR_5ggNYlp-k,3223
|
|
36
36
|
rapyer/types/__init__.py,sha256=lM2ZdpkgWW_7eh0AXoabtgA9CGhzWUHOi9W0_RTqu6I,484
|
|
37
37
|
rapyer/types/base.py,sha256=AA7E0knCy9dJd78O0APG5FEUXvHSqWknzkp3Rpj1O30,6034
|
|
38
38
|
rapyer/types/byte.py,sha256=cnV-XMMPKv03tV0oKSJ1mlrpwdAygs4H_EhOVheu-2Q,1791
|
|
39
39
|
rapyer/types/convert.py,sha256=nyElDMWaWXtI_dXpAAg5elqWo439HsZ6u6wLj9WuHsI,3548
|
|
40
40
|
rapyer/types/datetime.py,sha256=EuT6XhFPfQWNtGRd_8bX3DWm6_EGo-HqMef9Fr3fiNQ,4294
|
|
41
|
-
rapyer/types/dct.py,sha256
|
|
41
|
+
rapyer/types/dct.py,sha256=zsBJdA-y6UTUmc88q9h9Vhcjcdk-OJ18fJSRLvAe7LQ,6587
|
|
42
42
|
rapyer/types/float.py,sha256=4TEKOJ778MFogULlfRq8iQV9bYdx-eArgRTtmeRzeP4,2864
|
|
43
43
|
rapyer/types/init.py,sha256=SGH2uH9dIkWfaTMdiD-YV053nwRPaxUs4jTG1gOA2dg,495
|
|
44
44
|
rapyer/types/integer.py,sha256=TvpFehA4LNvYWapaOph9izkWuf9eAAKqkPicjsKaz9s,2381
|
|
@@ -50,6 +50,6 @@ rapyer/utils/annotation.py,sha256=MB01l2k9g10AOSfttVfDIUc7JBzZWdH_Cn9FDe0IEGo,30
|
|
|
50
50
|
rapyer/utils/fields.py,sha256=LhIhnuRBNrtE3RyFI-AiScXTzqYmOfcm-rdtmcdaHM0,2815
|
|
51
51
|
rapyer/utils/pythonic.py,sha256=Xiv7RLqLozgLuwZSPIxBlsypIyoIYmPG_lV78TI4r80,141
|
|
52
52
|
rapyer/utils/redis.py,sha256=d4qhR7QsER0572NMis_ATUUC17Jo4h9r8TKHTF8OIds,441
|
|
53
|
-
rapyer-1.2.
|
|
54
|
-
rapyer-1.2.
|
|
55
|
-
rapyer-1.2.
|
|
53
|
+
rapyer-1.2.1.dist-info/METADATA,sha256=lOK0hW34l7XZ75ewvyj8GaREF5EVYr9TXGmuVy_ZdZk,11418
|
|
54
|
+
rapyer-1.2.1.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
55
|
+
rapyer-1.2.1.dist-info/RECORD,,
|