Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

# encoding: utf-8 

from __future__ import print_function, division, absolute_import 

 

from datetime import datetime 

import os 

 

import yaml 

 

from .bunch import Bunch 

from .errors import ConsistencyError, FormatError 

from .logger import logger 

from .utils import iter_to_list 

 

 

def load_yaml_and_bunchify(path): 

path = os.path.abspath(path) 

with open(path, "rb") as fh: 

data = yaml.load(fh) 

return bunchify(data) 

 

 

def bunchify(obj): 

if isinstance(obj, dict): 

obj = {k: bunchify(v) for (k, v) in obj.items()} 

return Bunch(obj) 

elif isinstance(obj, list): 

obj = [bunchify(item) for item in obj] 

elif isinstance(obj, tuple): 

obj = tuple(bunchify(item) for item in obj) 

elif isinstance(obj, set): 

obj = set(bunchify(item) for item in obj) 

return obj 

 

 

def load_as_list_of_bunches(path): 

path = os.path.abspath(path) 

result = [] 

with open(path, "rb") as fh: 

data = yaml.load(fh) 

if data is None: 

return None 

for item in data: 

result.append(Bunch(item or {})) 

return result 

 

 

def parse_date(s): 

for fmt_string in ("%Y/%m/%d %H:%M:%S", "%Y/%m/%d"): 

try: 

return datetime.strptime(s, fmt_string) 

except ValueError: 

continue 

raise FormatError("invalid date format: could not parse {!r}".format(s)) 

 

 

@iter_to_list 

def check_yaml_fields_exist(bunch, path, check_attributes): 

""" 

"bunch" is a Bunch object holding data, eg site data. 

"path" is the location of the yaml file on on the file system, we need this for reporting 

errors 

"check_attributes" is a list of strings. every string may containt "." to check for 

chained attributes. 

""" 

 

already_failed = set() 

 

for attribute in check_attributes: 

 

if "." in attribute: 

prefix, __ = attribute.rsplit(".", 1) 

# if we already complained about parent we skip this check: 

if prefix in already_failed: 

continue 

 

temp_bunch = bunch 

for part in attribute.split("."): 

try: 

temp_bunch = temp_bunch[part] 

except KeyError: 

# we record attribute alone, makes testing easier: 

already_failed.add(attribute) 

if "." in attribute: 

parent, field = attribute.rsplit(".", 1) 

yield ConsistencyError("{}: attribute {} has no field '{}'".format(path, parent, field)) 

else: 

yield ConsistencyError("{} has no field '{}'".format(path, attribute)) 

break