Robot Framework
etreewrapper.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from io import BytesIO
17 from os import fsdecode
18 import re
19 
20 from .robottypes import is_bytes, is_pathlike, is_string
21 
22 try:
23  from xml.etree import cElementTree as ET
24 except ImportError:
25  try:
26  from xml.etree import ElementTree as ET
27  except ImportError:
28  raise ImportError('No valid ElementTree XML parser module found')
29 
30 
31 class ETSource:
32 
33  def __init__(self, source):
34  self._source_source = source
35  self._opened_opened = None
36 
37  def __enter__(self):
38  self._opened_opened = self._open_if_necessary_open_if_necessary(self._source_source)
39  return self._opened_opened or self._source_source
40 
41  def _open_if_necessary(self, source):
42  if self._is_path_is_path(source) or self._is_already_open_is_already_open(source):
43  return None
44  if is_bytes(source):
45  return BytesIO(source)
46  encoding = self._find_encoding_find_encoding(source)
47  return BytesIO(source.encode(encoding))
48 
49  def _is_path(self, source):
50  if is_pathlike(source):
51  return True
52  elif is_string(source):
53  prefix = '<'
54  elif is_bytes(source):
55  prefix = b'<'
56  else:
57  return False
58  return not source.lstrip().startswith(prefix)
59 
60  def _is_already_open(self, source):
61  return not (is_string(source) or is_bytes(source))
62 
63  def _find_encoding(self, source):
64  match = re.match(r"\s*<\?xml .*encoding=(['\"])(.*?)\1.*\?>", source)
65  return match.group(2) if match else 'UTF-8'
66 
67  def __exit__(self, exc_type, exc_value, exc_trace):
68  if self._opened_opened:
69  self._opened_opened.close()
70 
71  def __str__(self):
72  source = self._source_source
73  if self._is_path_is_path(source):
74  return self._path_to_string_path_to_string(source)
75  if hasattr(source, 'name'):
76  return self._path_to_string_path_to_string(source.name)
77  return '<in-memory file>'
78 
79  def _path_to_string(self, path):
80  if is_pathlike(path):
81  return str(path)
82  if is_bytes(path):
83  return fsdecode(path)
84  return path
def _is_already_open(self, source)
Definition: etreewrapper.py:60
def _open_if_necessary(self, source)
Definition: etreewrapper.py:41
def _find_encoding(self, source)
Definition: etreewrapper.py:63
def __exit__(self, exc_type, exc_value, exc_trace)
Definition: etreewrapper.py:67