Skip to content

Commit cfb3c03

Browse files
Merge pull request #91 from christianhelle/copilot/add-anonymous-instances-features
Add support for tuple, set, frozenset, dict, Decimal, UUID, Path, time, timedelta, and typing generics
2 parents 36f534b + c44884e commit cfb3c03

11 files changed

+1130
-2
lines changed

README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,27 @@ Built-in types:
131131
- range
132132
- bytes
133133
- bytearray
134+
- tuple
135+
- set
136+
- frozenset
137+
- dict
138+
- decimal.Decimal
139+
- uuid.UUID
140+
- pathlib.Path
134141

135142
Datetime types:
136143
- datetime
137144
- date
145+
- time
146+
- timedelta
147+
148+
Typing generics:
149+
- typing.Tuple[T, ...]
150+
- typing.Set[T]
151+
- typing.FrozenSet[T]
152+
- typing.Dict[K, V]
153+
- typing.Optional[T]
154+
- typing.List[T]
138155

139156
Classes:
140157
- Simple classes
@@ -174,6 +191,61 @@ anonymous datetime: 2017-06-19 02:40:41.000084
174191
anonymous date: 2019-11-10 00:00:00
175192
```
176193

194+
Create anonymous instances of additional built-in and standard library types
195+
196+
```python
197+
import decimal
198+
import uuid
199+
import pathlib
200+
from datetime import time, timedelta
201+
202+
print(f'anonymous tuple: {Autodata.create(tuple)}')
203+
print(f'anonymous set: {Autodata.create(set)}')
204+
print(f'anonymous frozenset: {Autodata.create(frozenset)}')
205+
print(f'anonymous dict: {Autodata.create(dict)}')
206+
print(f'anonymous Decimal: {Autodata.create(decimal.Decimal)}')
207+
print(f'anonymous UUID: {Autodata.create(uuid.UUID)}')
208+
print(f'anonymous Path: {Autodata.create(pathlib.Path)}')
209+
print(f'anonymous time: {Autodata.create(time)}')
210+
print(f'anonymous timedelta: {Autodata.create(timedelta)}')
211+
```
212+
213+
The code above might output the following
214+
215+
```
216+
anonymous tuple: (9655, '1608f20f-c563-41ff-b3df-2be21be71437', 2309.52)
217+
anonymous set: {'eff62089-1834-4b5c-854e-68ac8f28979f', ...}
218+
anonymous frozenset: frozenset({'0ef46f14-70ce-4d0b-a099-625d0f881602', ...})
219+
anonymous dict: {'fd1a7430-5b5f-4dc0-974d-65184a406d25': 3431, ...}
220+
anonymous Decimal: 2508.6919872240996
221+
anonymous UUID: 751de33e-401e-42f2-acdb-3df9d1f9eb62
222+
anonymous Path: ee388b30-eb11-46af-b2f0/e1ab4d2d-7a6f-4ee9
223+
anonymous time: 23:09:39.638523
224+
anonymous timedelta: 165 days, 1:19:58.470884
225+
```
226+
227+
Create anonymous instances of typed generics
228+
229+
```python
230+
from typing import Tuple, Set, FrozenSet, Dict, Optional
231+
232+
print(f'Tuple[int, str]: {Autodata.create(Tuple[int, str])}')
233+
print(f'Set[int]: {Autodata.create(Set[int])}')
234+
print(f'FrozenSet[str]: {Autodata.create(FrozenSet[str])}')
235+
print(f'Dict[str, int]: {Autodata.create(Dict[str, int])}')
236+
print(f'Optional[int]: {Autodata.create(Optional[int])}')
237+
```
238+
239+
The code above might output the following
240+
241+
```
242+
Tuple[int, str]: (7032, '351236d0-378e-45f6-bf58-77e2ac2bfc48')
243+
Set[int]: {1408, 8224, 5107}
244+
FrozenSet[str]: frozenset({'5f5eaf3c-1926-4d34-ae32-ef5a3a549c5f', ...})
245+
Dict[str, int]: {'65174a9b-76f3-4d1c-a1a4': 3817, ...}
246+
Optional[int]: 8051
247+
```
248+
177249
Creates an anonymous class
178250

179251
```python
@@ -380,6 +452,62 @@ inner.id = 1705149100
380452
inner.text = e703a117-ba4f-4201-a31b-10ab8e54a673
381453
```
382454

455+
Create a dataclass using additional built-in types and typing generics
456+
457+
```python
458+
import decimal
459+
import uuid
460+
import pathlib
461+
from datetime import time, timedelta
462+
from typing import Set, Dict, Tuple, Optional
463+
from dataclasses import dataclass
464+
from autofaker import Autodata
465+
466+
@dataclass
467+
class AdvancedDataClass:
468+
id: int
469+
name: str
470+
amount: decimal.Decimal
471+
uid: uuid.UUID
472+
file_path: pathlib.Path
473+
created_time: time
474+
duration: timedelta
475+
tags: Set[str]
476+
scores: Tuple[int, str]
477+
metadata: Dict[str, int]
478+
optional_name: Optional[str]
479+
480+
data = Autodata.create(AdvancedDataClass)
481+
482+
print(f'id: {data.id}')
483+
print(f'name: {data.name}')
484+
print(f'amount: {data.amount}')
485+
print(f'uid: {data.uid}')
486+
print(f'file_path: {data.file_path}')
487+
print(f'created_time: {data.created_time}')
488+
print(f'duration: {data.duration}')
489+
print(f'tags: {data.tags}')
490+
print(f'scores: {data.scores}')
491+
print(f'metadata: {data.metadata}')
492+
print(f'optional: {data.optional_name}')
493+
```
494+
495+
The code above might output the following
496+
497+
```
498+
id: 2225
499+
name: 28a78977-8218-471a-aa3b-5172bd267e9a
500+
amount: 8071.9111587519055
501+
uid: 4bfc05f9-ad4e-4906-96a0-74f4ef60974f
502+
file_path: 0da7ee48-1008-4e72/ffc6c087-b690-44d3
503+
created_time: 15:25:29.820442
504+
duration: 177 days, 23:33:16.414807
505+
tags: {'191751c3-11a6-471b', '63508ce7-b14a-433f', ...}
506+
scores: (4467, 'a1255ae9-b23c-4cfa-8861-213e12b41030')
507+
metadata: {'193b3ddc-3172-49ef': 1744, ...}
508+
optional: 983e4c69-0426-4488-ba98-559e77075c03
509+
```
510+
383511
Create a Pandas DataFrame using anonymous data generated from a specified type
384512

385513
```python

src/autofaker/builtins.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import decimal
2+
import pathlib
13
import random
24
import uuid
35

@@ -47,3 +49,57 @@ def generate(self):
4749
class MemoryViewGenerator(TypeDataGeneratorBase):
4850
def generate(self):
4951
return memoryview(BytesGenerator().generate())
52+
53+
54+
class TupleGenerator(TypeDataGeneratorBase):
55+
def generate(self):
56+
return (
57+
IntegerGenerator().generate(),
58+
StringGenerator().generate(),
59+
FloatGenerator().generate(),
60+
)
61+
62+
63+
class SetGenerator(TypeDataGeneratorBase):
64+
def generate(self):
65+
return {
66+
StringGenerator().generate(),
67+
StringGenerator().generate(),
68+
StringGenerator().generate(),
69+
}
70+
71+
72+
class FrozenSetGenerator(TypeDataGeneratorBase):
73+
def generate(self):
74+
return frozenset({
75+
StringGenerator().generate(),
76+
StringGenerator().generate(),
77+
StringGenerator().generate(),
78+
})
79+
80+
81+
class DictGenerator(TypeDataGeneratorBase):
82+
def generate(self):
83+
return {
84+
StringGenerator().generate(): IntegerGenerator().generate(),
85+
StringGenerator().generate(): IntegerGenerator().generate(),
86+
StringGenerator().generate(): IntegerGenerator().generate(),
87+
}
88+
89+
90+
class DecimalGenerator(TypeDataGeneratorBase):
91+
def generate(self):
92+
return decimal.Decimal(str(random.uniform(0, 10000)))
93+
94+
95+
class UUIDGenerator(TypeDataGeneratorBase):
96+
def generate(self):
97+
return uuid.uuid4()
98+
99+
100+
class PathGenerator(TypeDataGeneratorBase):
101+
def generate(self):
102+
return pathlib.Path(
103+
StringGenerator().generate(),
104+
StringGenerator().generate(),
105+
)

src/autofaker/dates.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
def is_date_type(type_name) -> bool:
8-
return type_name in ["datetime", "date"]
8+
return type_name in ["datetime", "date", "time", "timedelta"]
99

1010

1111
class DatetimeGenerator(TypeDataGeneratorBase):
@@ -30,3 +30,22 @@ def generate(self):
3030
random.randint(1, 12),
3131
random.randint(1, 28),
3232
)
33+
34+
35+
class TimeGenerator(TypeDataGeneratorBase):
36+
def generate(self):
37+
return datetime.time(
38+
random.randint(0, 23),
39+
random.randint(0, 59),
40+
random.randint(0, 59),
41+
random.randint(0, 999999),
42+
)
43+
44+
45+
class TimedeltaGenerator(TypeDataGeneratorBase):
46+
def generate(self):
47+
return datetime.timedelta(
48+
days=random.randint(0, 365),
49+
seconds=random.randint(0, 86399),
50+
microseconds=random.randint(0, 999999),
51+
)

src/autofaker/factory.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
ByteArrayGenerator,
44
BytesGenerator,
55
ComplexGenerator,
6+
DecimalGenerator,
7+
DictGenerator,
68
FloatGenerator,
9+
FrozenSetGenerator,
710
IntegerGenerator,
811
MemoryViewGenerator,
12+
PathGenerator,
913
RangeGenerator,
14+
SetGenerator,
15+
TupleGenerator,
16+
UUIDGenerator,
1017
)
1118
from autofaker.fakes import FakeIntegerGenerator, FakeStringGenerator, StringGenerator
1219

@@ -24,6 +31,15 @@ def is_supported(type_name) -> bool:
2431
"bytes",
2532
"bytearray",
2633
"memoryview",
34+
"tuple",
35+
"set",
36+
"frozenset",
37+
"dict",
38+
"decimal",
39+
"uuid",
40+
"posixpath",
41+
"windowspath",
42+
"path",
2743
]
2844

2945
@staticmethod
@@ -54,3 +70,17 @@ def create(type_name, field_name: str = None, use_fake_data: bool = False):
5470
return ByteArrayGenerator()
5571
if type_name == "memoryview":
5672
return MemoryViewGenerator()
73+
if type_name == "tuple":
74+
return TupleGenerator()
75+
if type_name == "set":
76+
return SetGenerator()
77+
if type_name == "frozenset":
78+
return FrozenSetGenerator()
79+
if type_name == "dict":
80+
return DictGenerator()
81+
if type_name == "decimal":
82+
return DecimalGenerator()
83+
if type_name == "uuid":
84+
return UUIDGenerator()
85+
if type_name in ("posixpath", "windowspath", "path"):
86+
return PathGenerator()

0 commit comments

Comments
 (0)