Skip to content

Commit 633a89f

Browse files
committed
2 parents 5d46e54 + 03b40e3 commit 633a89f

File tree

6 files changed

+25
-14
lines changed

6 files changed

+25
-14
lines changed

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
setuptools==63.2.0
1+
setuptools==65.5.1
22
requests~=2.28.1
33
urllib3~=1.26.11

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def read(filename):
1515

1616
setup(
1717
name="py-xbrl",
18-
version="2.2.3",
18+
version="2.2.6",
1919
url="https://github.com/manusimidt/xbrl_parser",
2020
license='GNU General Public License v3 (GPLv3)',
2121
author="Manuel Schmidt",

xbrl/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class ContextParseException(InstanceParseException):
7676
pass
7777

7878

79-
__version__ = '2.2.3'
79+
__version__ = '2.2.6'
8080
__author__ = 'Manuel Schmidt <[email protected]>'
8181
__all__ = [
8282
XbrlParseException,

xbrl/instance.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,12 @@ def __str__(self) -> str:
286286
file_name: str = self.instance_url.split('/')[-1]
287287
return "{} with {} facts".format(file_name, len(self.facts))
288288

289-
def json(self, file_path: str = None, override_fact_ids: bool = True) -> str or None:
289+
def json(self, file_path: str = None, override_fact_ids: bool = True, **kwargs) -> str or None:
290290
"""
291291
Converts the instance document into json format
292292
:param file_path: if a path is given the function will store the json there
293293
:param override_fact_ids:
294+
:param kwargs: additional arguments for the json parser
294295
:return: string (serialized json) or None (if file_path was given)
295296
296297
https://www.xbrl.org/Specification/xbrl-json/REC-2021-10-13/xbrl-json-REC-2021-10-13.html
@@ -308,9 +309,9 @@ def json(self, file_path: str = None, override_fact_ids: bool = True) -> str or
308309
json_dict['facts'][fact_id] = fact.json()
309310
if file_path:
310311
with open(file_path, 'w', encoding='utf8') as f:
311-
return json.dump(json_dict, f)
312+
return json.dump(json_dict, f, **kwargs)
312313
else:
313-
return json.dumps(json_dict)
314+
return json.dumps(json_dict, **kwargs)
314315

315316

316317
def parse_xbrl_url(instance_url: str, cache: HttpCache) -> XbrlInstance:
@@ -409,16 +410,17 @@ def parse_xbrl(instance_path: str, cache: HttpCache, instance_url: str or None =
409410
return XbrlInstance(instance_url if instance_url else instance_path, taxonomy, facts, context_dir, unit_dir)
410411

411412

412-
def parse_ixbrl_url(instance_url: str, cache: HttpCache) -> XbrlInstance:
413+
def parse_ixbrl_url(instance_url: str, cache: HttpCache, encoding: str or None = None) -> XbrlInstance:
413414
"""
414415
Parses a inline XBRL (iXBRL) instance file.
415416
416417
:param cache: HttpCache instance
417418
:param instance_url: url to the instance file(on the internet)
419+
:param encoding: specifies the encoding of the file
418420
:return: parsed XbrlInstance object containing all facts with additional information
419421
"""
420422
instance_path: str = cache.cache_file(instance_url)
421-
return parse_ixbrl(instance_path, cache, instance_url)
423+
return parse_ixbrl(instance_path, cache, instance_url, encoding)
422424

423425

424426
def parse_ixbrl(instance_path: str, cache: HttpCache, instance_url: str or None = None, encoding=None, schema_root=None) -> XbrlInstance:
@@ -708,7 +710,7 @@ class XbrlParser:
708710
def __init__(self, cache: HttpCache):
709711
self.cache = cache
710712

711-
def parse_instance(self, uri: str, instance_url: str or None = None) -> XbrlInstance:
713+
def parse_instance(self, uri: str, instance_url: str or None = None, encoding: str or None = None) -> XbrlInstance:
712714
"""
713715
Parses a xbrl instance (either xbrl or ixbrl)
714716
@@ -721,11 +723,14 @@ def parse_instance(self, uri: str, instance_url: str or None = None) -> XbrlInst
721723
i.e: https://www.sec.gov/Archives/edgar/data/320193/000032019320000096/aapl-20200926.
722724
:param instance_url: this parameter overrides the above described behaviour. If you also provide the url where the
723725
instance document was downloaded, the parser can fetch relative imports using this base url
726+
:param encoding: specifies the encoding of the file
724727
:return:
725728
"""
726729
if uri.split('.')[-1] == 'xml' or uri.split('.')[-1] == 'xbrl':
727-
return parse_xbrl_url(uri, self.cache) if uri.startswith('http') else parse_xbrl(uri, self.cache, instance_url)
728-
return parse_ixbrl_url(uri, self.cache) if uri.startswith('http') else parse_ixbrl(uri, self.cache, instance_url)
730+
return parse_xbrl_url(uri, self.cache) if uri.startswith('http') \
731+
else parse_xbrl(uri, self.cache, instance_url)
732+
return parse_ixbrl_url(uri, self.cache) if uri.startswith('http') \
733+
else parse_ixbrl(uri, self.cache, instance_url, encoding)
729734

730735
def __str__(self) -> str:
731736
return 'XbrlParser with cache dir at {}'.format(self.cache.cache_dir)

xbrl/linkbase.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,16 @@ class Linkbase:
383383
Represents a complete Linkbase (non-generic).
384384
"""
385385

386-
def __init__(self, extended_links: List[ExtendedLink], linkbase_type: LinkbaseType) -> None:
386+
def __init__(self, extended_links: List[ExtendedLink], linkbase_type: LinkbaseType, linkbase_uri: None or str = None) -> None:
387387
"""
388388
:param extended_links: All standard extended links that are defined in the linkbase
389389
:type extended_links: [ExtendedDefinitionLink] or [ExtendedCalculationLink] or [ExtendedPresentationLink] or [ExtendedLabelArc]
390390
:param linkbase_type: Type of the linkbase
391+
:param linkbase_uri: Either the path or the url to the linkbase (depends from where the parser loaded it for parsing)
391392
"""
392393
self.extended_links: List[ExtendedLink] = extended_links
393394
self.type = linkbase_type
395+
self.linkbase_uri = linkbase_uri
394396

395397
def to_dict(self) -> dict:
396398
"""
@@ -564,4 +566,4 @@ def parse_linkbase(linkbase_path: str, linkbase_type: LinkbaseType, linkbase_url
564566
ExtendedLink(extended_link_role, role_refs[extended_link_role], root_locators))
565567
elif linkbase_type == LinkbaseType.LABEL:
566568
extended_links.append(ExtendedLink(extended_link_role, None, root_locators))
567-
return Linkbase(extended_links, linkbase_type)
569+
return Linkbase(extended_links, linkbase_type, linkbase_url if linkbase_url else linkbase_path)

xbrl/transformations/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,11 @@ def normalize(namespace: str, formatCode: str, value: str) -> str:
577577
value = value.strip().lower()
578578

579579
try:
580-
if namespace == 'http://www.xbrl.org/inlineXBRL/transformation/2010-04-20':
580+
if namespace == 'http://www.xbrl.org/2008/inlineXBRL/transformation':
581+
# WARNING: I could not find a specification for this ancient transformation registry..
582+
# however the transformations will probably be the same as defined in the 2010 version
583+
return ixt[formatCode](value)
584+
elif namespace == 'http://www.xbrl.org/inlineXBRL/transformation/2010-04-20':
581585
return ixt[formatCode](value)
582586
elif namespace == 'http://www.xbrl.org/2008/inlineXBRL/transformation':
583587
return ixt[formatCode](value)

0 commit comments

Comments
 (0)