Skip to content

Commit c206424

Browse files
authored
Towards handling Import[xxx, "ZIP", member-name] (#1846)
Plumbing hooked up for Import zip with members. Now we just gotta get ImportString[xxx, "JSON"] working on its own. Also, other small fixes and improvements. More changes to `Import` will be made in a future PR.
1 parent 23f114d commit c206424

19 files changed

Lines changed: 555 additions & 394 deletions

File tree

SYMBOLS_MANIFEST.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
Compress`ImportZIP
12
HTML`DataImport
23
HTML`FullDataImport
34
HTML`HyperlinksImport
@@ -12,7 +13,7 @@ ImportExport`RegisterExport
1213
ImportExport`RegisterImport
1314
Internal`RealValuedNumberQ
1415
Internal`RealValuedNumericQ
15-
JSON`Import`JSONImport
16+
JSON`ImportJSON
1617
System`$Aborted
1718
System`$Assumptions
1819
System`$BaseDirectory
@@ -582,9 +583,7 @@ System`ImageTake
582583
System`ImageType
583584
System`Implies
584585
System`Import
585-
System`ImportJSON
586586
System`ImportString
587-
System`ImportZIP
588587
System`In
589588
System`Increment
590589
System`Indeterminate

mathics/SystemFiles/Formats/JSON/Import.wl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
(* ::Package:: *)
22

3+
(* JSON Javascript Object Notation or JSON web service description Importer.
4+
This is used by Import[] and, ImportString[].
5+
*)
6+
37
Begin["System`Convert`JSONDump`"]
48

59
(* JSON legacy element is Data even if Expression would be better. *)
610
$AvailableElements = {"Data", "Dataset"};
711

812
ImportExport`RegisterImport[
9-
"JSON",
10-
ImportJSON,
13+
"JSON", (* WMA mime-type name *)
14+
JSON`ImportJSON, (* Default Function name that handles this. *)
1115
{},
12-
"AvailableElements" -> $AvailableElements,
16+
"AvailableElements" -> $AvailableElements, (* names retuned by "Elements" query *)
1317
"FunctionChannels" -> {"FileNames"},
1418
"DefaultElement" -> "Data"
1519
]

mathics/SystemFiles/Formats/ZIP/Import.wl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(* ::Package:: *)
22

3-
(* ZIP compressed file and file archive Importer.
4-
This is used by Import[].
3+
(* Windows ZIP archive, ZIP compressed file and file archive Importer.
4+
This is used by Import[] and, ImportString[].
55
*)
66

77
Begin["System`Convert`CommonArchiveDump`"]
@@ -21,13 +21,13 @@ GetElements[___] :=
2121
];
2222

2323
ImportExport`RegisterImport[
24-
"ZIP",
25-
ImportZIP,
24+
"ZIP", (* WMA mime-type name *)
25+
Compress`ImportZIP, (* Default Function name that handles this. *)
2626
{}, (* Post importer function(s) *)
2727
FunctionChannels -> {"FileNames"},
2828
(* WMA has this, but I (rocky) am not sure why or what it means:
2929
AvailableElements -> $ZIPAvailableElements, *)
30-
AvailableElements -> {"Filenames", "Summary"},
30+
AvailableElements -> {"Filenames", "Summary"}, (* names retuned by "Elements" query *)
3131
BinaryFormat -> True,
3232
DefaultElement -> "FileNames",
3333
HiddenElements -> $ZIPHiddenElements,
Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
1-
"""
2-
File Formats
1+
r"""Import/Export File Formats, Importers and Exporters
2+
3+
The data of files on a filesystem or retrieved from the Internet often are structured \
4+
according to a specific structures and rules. For example, consider different kinds of \
5+
structuring used in a JSON file, versus an HTML files, or a compressed GZIP file.
6+
7+
In some cases, such as archive files, e.g., ZIP, TAR, and JAR, the file contains component parts, \
8+
which in WMA terminology are called "members" which is part of the broader metadata items \
9+
called "elements".
10+
11+
A MIME type is typically associated with each kind of format. \Mathics3, following WMA, \
12+
uses a shortend name for this MIME type. For example \Mathics3 uses "HTML" as a shorthand \
13+
for the MIME type "text/html".
14+
15+
Below is a list of file supported file types that we have builtin importers or exporters written \
16+
in Python. Other importers, however, are written in \Mathics3.
17+
18+
Variable <url>
19+
:\$ExportFormats:
20+
/doc/reference-of-built-in-symbols/inputoutput-files-and-filesystem/importing-and-exporting/\$exportformats</url> \
21+
contains a list of file formats that are supported by <url>
22+
:Export:
23+
/doc/reference-of-built-in-symbols/inputoutput-files-and-filesystem/importing-and-exporting/export</url>, \
24+
while <url>
25+
:\$ImportFormats:
26+
/doc/reference-of-built-in-symbols/inputoutput-files-and-filesystem/importing-and-exporting/\$importformats</url> \
27+
does the corresponding thing for <url>
28+
:Import:
29+
/doc/reference-of-built-in-symbols/inputoutput-files-and-filesystem/importing-and-exporting/import</url>.
330
4-
Built-in Importers.
31+
Many Import/Export functions are registered in SystemFiles/Formats/*.wl which is \
32+
autoloaded on startup.
533
34+
The Built-in Functions are defined in a separate context.
35+
For example, HTML` or Compress`. This is done to not pollute the System` namespace.
636
"""
737

8-
# The Built-in Functions are defined in a separate context under the
9-
# System`. For example System`HTML` and System`XML. This is done to not
10-
# pollute the System` namespace.
38+
# This tells documentation how to sort this module
39+
# Here we are also hiding "file_io" since this can erroneously appear at the top level.
40+
sort_order = "mathics.builtin.importing-export-file-formats"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Compression & Archive Formats
3+
"""
4+
5+
from mathics.core.builtin import Builtin, String
6+
from mathics.core.evaluation import Evaluation
7+
from mathics.eval.fileformats.compression import eval_ImportZIP
8+
9+
# See commit in __init__.py regarding the whacky way this gets called
10+
11+
12+
class ImportZIP(Builtin):
13+
"""
14+
<url>:WMA link:https://reference.wolfram.com/language/ref/format/ZIP.html</url>
15+
16+
<dl>
17+
<dt>'Compress`ImportZIP[path]'
18+
<dd>Run zip for archive file $path$
19+
</dl>
20+
21+
"""
22+
23+
context = "Compress`"
24+
summary_text = "import a ZIP file"
25+
26+
def eval(self, path: String, evaluation: Evaluation):
27+
"Compress`ImportZIP[path_String]"
28+
return eval_ImportZIP(path, evaluation)
29+
30+
def eval_with_elements(self, path: String, elements, evaluation: Evaluation):
31+
"Compress`ImportZIP[path_String, elements_]"
32+
return eval_ImportZIP(path, evaluation, elements)

mathics/builtin/fileformats/htmlformat.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""
33
HTML
44
5-
Basic implementation for a HTML importer.
5+
HTML importer.
66
"""
77

88

@@ -15,6 +15,7 @@
1515
from mathics.core.builtin import Builtin, MessageException
1616
from mathics.core.convert.expression import to_expression, to_mathics_list
1717
from mathics.core.convert.python import from_python
18+
from mathics.core.evaluation import Evaluation
1819
from mathics.core.expression import Expression
1920
from mathics.core.list import ListExpression
2021
from mathics.core.symbols import Symbol
@@ -126,7 +127,7 @@ class _TagImport(_HTMLBuiltin):
126127
def _import(self, tree):
127128
raise NotImplementedError
128129

129-
def eval(self, text, evaluation):
130+
def eval(self, text: String, evaluation: Evaluation):
130131
"""%(name)s[text_String]"""
131132
tree = parse_html(parse_html_file, text, evaluation)
132133
if isinstance(tree, Symbol): # $Failed?
@@ -135,6 +136,12 @@ def eval(self, text, evaluation):
135136
to_expression(SymbolRule, self.tag_name, self._import(tree))
136137
)
137138

139+
def eval_with_element(self, text, element, evaluation: Evaluation):
140+
"""%(name)s[text_String, element_]"""
141+
# FIXME: right now we aren't using element, and should use this to more
142+
# efficiently extract part of the XML file that we want.
143+
return self.eval(text, evaluation)
144+
138145

139146
class _Get(_HTMLBuiltin):
140147
context = "HTML`Parser`"
@@ -401,7 +408,7 @@ class SourceImport(_HTMLBuiltin):
401408

402409
summary_text = "import source code from a HTML file"
403410

404-
def eval(self, text, evaluation):
411+
def eval(self, text, evaluation: Evaluation):
405412
"""%(name)s[text_String]"""
406413

407414
def source(filename):
@@ -412,6 +419,12 @@ def source(filename):
412419

413420
return parse_html(source, text, evaluation)
414421

422+
def eval_with_element(self, text, element, evaluation: Evaluation):
423+
"""%(name)s[text_String, element_]"""
424+
# FIXME: right now we aren't using element, and should use this to more
425+
# efficiently extract part of the XML file that we want.
426+
return self.eval(text, evaluation)
427+
415428

416429
class TitleImport(_TagImport):
417430
"""
@@ -437,7 +450,7 @@ def _import(self, tree):
437450

438451
class XMLObjectImport(_HTMLBuiltin):
439452
"""
440-
## <url>:native internal:</url>
453+
<url>:WMA link:https://reference.wolfram.com/language/ref/XMLObject.html</url>
441454
442455
<dl>
443456
<dt>'HTML`XMLObjectImport["filename"]'
@@ -450,7 +463,13 @@ class XMLObjectImport(_HTMLBuiltin):
450463

451464
summary_text = "import XML objects from a HTML file"
452465

453-
def eval(self, text, evaluation):
466+
def eval(self, text, evaluation: Evaluation):
454467
"""%(name)s[text_String]"""
455468
xml = to_expression("HTML`Parser`HTMLGet", text).evaluate(evaluation)
456469
return ListExpression(Expression(SymbolRule, String("XMLObject"), xml))
470+
471+
def eval_with_element(self, text, element, evaluation: Evaluation):
472+
"""%(name)s[text_String, element_]"""
473+
# FIXME: right now we aren't using element, and should use this to more
474+
# efficiently extract part of the HTML file that we want.
475+
return self.eval(text, evaluation)
Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""
4-
JSON
2+
JSON File Format
53
6-
Basic implementation for an JSON importer.
4+
JSON importer (via Python's "json" module).
75
"""
86

9-
from mathics.core.builtin import Builtin
10-
from mathics.core.expression import Evaluation
7+
from mathics.core.builtin import Builtin, String
8+
from mathics.core.evaluation import Evaluation
119
from mathics.eval.fileformats.jsonformat import eval_JSONImport
1210

1311

14-
class JSONImport(Builtin):
12+
class ImportJSON(Builtin):
1513
"""
16-
## <url>:native internal:</url>
14+
<url>:WMA link:https://reference.wolfram.com/language/ref/format/JSON.html</url>
1715
1816
<dl>
19-
<dt>'JSON`Import`JSONImport["file"]'
20-
<dd>parses "string" as a JSON file, and returns the data as a nested \
21-
list of rules.
17+
<dt>'JSON`ImportJSON[path]'
18+
<dd>Read $path$ as JSON and convert that to its corresponding Mathics3 equivalent.
2219
</dl>
2320
2421
"""
2522

26-
summary_text = "import elements from json"
27-
context = "JSON`Import`"
23+
context = "JSON`"
2824
messages = {"dec": "Decoding Error at `1`"}
25+
summary_text = "import JSON file"
2926

30-
def eval(self, filename, evaluation: Evaluation):
31-
"""%(name)s[filename_String]"""
32-
return eval_JSONImport(filename.value, evaluation)
27+
def eval(self, path: String, evaluation: Evaluation):
28+
"JSON`ImportJSON[path_String]"
29+
return eval_JSONImport(path, evaluation)

mathics/builtin/fileformats/xmlformat.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# -*- coding: utf-8 -*-
22

33
"""
4-
XML
4+
XML File Format
55
6-
Basic implementation for an XML importer.
6+
XML importer (via lxml).
77
"""
88

99

@@ -345,6 +345,12 @@ def lines():
345345
plaintext = String("\n".join(lines()))
346346
return to_mathics_list(to_expression("Rule", "Plaintext", plaintext))
347347

348+
def eval_with_element(self, text, element, evaluation: Evaluation):
349+
"""%(name)s[text_String, element_]"""
350+
# FIXME: right now we aren't using element, and should use this to more
351+
# efficiently extract part of the XML file that we want.
352+
return self.eval(text, evaluation)
353+
348354

349355
class TagsImport(Builtin):
350356
"""
@@ -381,6 +387,12 @@ def eval(self, text, evaluation: Evaluation):
381387
return root
382388
return to_mathics_list(to_expression("Rule", "Tags", self._tags(root)))
383389

390+
def eval_with_element(self, text, element, evaluation: Evaluation):
391+
"""%(name)s[text_String, element_]"""
392+
# FIXME: right now we aren't using element, and should use this to more
393+
# efficiently extract part of the XML file that we want.
394+
return self.eval(text, evaluation)
395+
384396

385397
class XMLObjectImport(Builtin):
386398
"""
@@ -405,3 +417,9 @@ def eval(self, text, evaluation: Evaluation):
405417
"""%(name)s[text_String]"""
406418
xml = to_expression("XML`Parser`XMLGet", text).evaluate(evaluation)
407419
return to_mathics_list(to_expression("Rule", "XMLObject", xml))
420+
421+
def eval_with_element(self, text, element, evaluation: Evaluation):
422+
"""%(name)s[text_String, element_]"""
423+
# FIXME: right now we aren't using element, and should use this to more
424+
# efficiently extract part of the XML file that we want.
425+
return self.eval(text, evaluation)

mathics/builtin/import_export/compression.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)