-
Notifications
You must be signed in to change notification settings - Fork 10
/
__init__.py
149 lines (122 loc) · 3.76 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import importlib
import sys
from contextlib import contextmanager
from typing import Callable, Optional
from itemadapter import ItemAdapter
def make_mock_import(block_name: str) -> Callable:
def mock_import(name: str, *args, **kwargs):
"""Prevent importing a specific module, let everything else pass."""
if name.split(".")[0] == block_name:
raise ImportError(name)
return importlib.__import__(name, *args, **kwargs)
return mock_import
@contextmanager
def clear_itemadapter_imports() -> None:
backup = {}
for key in sys.modules.copy().keys():
if key.startswith("itemadapter"):
backup[key] = sys.modules.pop(key)
try:
yield
finally:
sys.modules.update(backup)
try:
import attr
except ImportError:
AttrsItem = None
AttrsItemNested = None
AttrsItemWithoutInit = None
else:
@attr.s
class AttrsItem:
name = attr.ib(default=None, metadata={"serializer": str})
value = attr.ib(default=None, metadata={"serializer": int})
@attr.s
class AttrsItemNested:
nested = attr.ib(type=AttrsItem)
adapter = attr.ib(type=ItemAdapter)
dict_ = attr.ib(type=dict)
list_ = attr.ib(type=list)
set_ = attr.ib(type=set)
tuple_ = attr.ib(type=tuple)
int_ = attr.ib(type=int)
@attr.s(init=False)
class AttrsItemWithoutInit:
name = attr.ib(default=None, metadata={"serializer": str})
value = attr.ib(default=None, metadata={"serializer": int})
try:
from dataclasses import dataclass, field
except ImportError:
DataClassItem = None
DataClassItemNested = None
DataClassWithoutInit = None
else:
@dataclass
class DataClassItem:
name: str = field(default_factory=lambda: None, metadata={"serializer": str})
value: int = field(default_factory=lambda: None, metadata={"serializer": int})
@dataclass
class DataClassItemNested:
nested: DataClassItem
adapter: ItemAdapter
dict_: dict
list_: list
set_: set
tuple_: tuple
int_: int
@dataclass(init=False)
class DataClassWithoutInit:
name: str = field(metadata={"serializer": str})
value: int = field(metadata={"serializer": int})
try:
from pydantic import BaseModel, Field as PydanticField
except ImportError:
PydanticModel = None
PydanticSpecialCasesModel = None
PydanticModelNested = None
else:
class PydanticModel(BaseModel):
name: Optional[str] = PydanticField(
default_factory=lambda: None,
serializer=str,
)
value: Optional[int] = PydanticField(
default_factory=lambda: None,
serializer=int,
)
class PydanticSpecialCasesModel(BaseModel):
special_cases: Optional[int] = PydanticField(
default_factory=lambda: None,
alias="special_cases",
allow_mutation=False,
)
class Config:
validate_assignment = True
class PydanticModelNested(BaseModel):
nested: PydanticModel
adapter: ItemAdapter
dict_: dict
list_: list
set_: set
tuple_: tuple
int_: int
class Config:
arbitrary_types_allowed = True
try:
from scrapy.item import Item as ScrapyItem, Field
except ImportError:
ScrapyItem = None
ScrapySubclassedItem = None
ScrapySubclassedItemNested = None
else:
class ScrapySubclassedItem(ScrapyItem):
name = Field(serializer=str)
value = Field(serializer=int)
class ScrapySubclassedItemNested(ScrapyItem):
nested = Field()
adapter = Field()
dict_ = Field()
list_ = Field()
set_ = Field()
tuple_ = Field()
int_ = Field()