18874: Merge commit '6f8dcb2b13f3058db656908fb26b09e23b527f08' into 18874-merge-wb2
[arvados.git] / sdk / python / discovery2pydoc.py
index 889ee93293a5edd75b3858e9747a1cb18cd00e3a..9f7f87d988e64534f196ff087a366be21dd6e9ff 100755 (executable)
@@ -86,11 +86,21 @@ generated dynamically at runtime when the client object is built.
 '''
 _SCHEMA_PYDOC = '''
 
 '''
 _SCHEMA_PYDOC = '''
 
-This is the dictionary object that represents a single {cls_name} in Arvados.
+This is the dictionary object that represents a single {cls_name} in Arvados
+and is returned by most `{cls_name}s` methods.
 The keys of the dictionary are documented below, along with their types.
 Not every key may appear in every dictionary returned by an API call.
 The keys of the dictionary are documented below, along with their types.
 Not every key may appear in every dictionary returned by an API call.
-Refer to the API documentation for details about how to retrieve specific keys
-if you need them.
+When a method doesn't return all the data, you can use its `select` parameter
+to list the specific keys you need. Refer to the API documentation for details.
+'''
+
+_MODULE_PRELUDE = '''
+import sys
+if sys.version_info < (3, 8):
+    from typing import Any
+    from typing_extensions import TypedDict
+else:
+    from typing import Any, TypedDict
 '''
 
 _TYPE_MAP = {
 '''
 
 _TYPE_MAP = {
@@ -200,7 +210,7 @@ class Method:
 
     def signature(self) -> inspect.Signature:
         parameters = [
 
     def signature(self) -> inspect.Signature:
         parameters = [
-            inspect.Parameter('self', inspect.Parameter.POSITIONAL_ONLY),
+            inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
             *self._required_params,
             *self._optional_params,
         ]
             *self._required_params,
             *self._optional_params,
         ]
@@ -308,16 +318,18 @@ If not provided, retrieved dynamically from Arvados client configuration.
         parts = urllib.parse.urlsplit(args.discovery_url)
         if not (parts.scheme or parts.netloc):
             args.discovery_url = pathlib.Path(args.discovery_url).resolve().as_uri()
         parts = urllib.parse.urlsplit(args.discovery_url)
         if not (parts.scheme or parts.netloc):
             args.discovery_url = pathlib.Path(args.discovery_url).resolve().as_uri()
+    # Our output is Python source, so it should be UTF-8 regardless of locale.
     if args.output_file == STDSTREAM_PATH:
     if args.output_file == STDSTREAM_PATH:
-        args.out_file = sys.stdout
+        args.out_file = open(sys.stdout.fileno(), 'w', encoding='utf-8', closefd=False)
     else:
     else:
-        args.out_file = args.output_file.open('w')
+        args.out_file = args.output_file.open('w', encoding='utf-8')
     return args
 
 def main(arglist: Optional[Sequence[str]]=None) -> int:
     args = parse_arguments(arglist)
     with urllib.request.urlopen(args.discovery_url) as discovery_file:
     return args
 
 def main(arglist: Optional[Sequence[str]]=None) -> int:
     args = parse_arguments(arglist)
     with urllib.request.urlopen(args.discovery_url) as discovery_file:
-        if not (discovery_file.status is None or 200 <= discovery_file.status < 300):
+        status = discovery_file.getcode()
+        if not (status is None or 200 <= status < 300):
             print(
                 f"error getting {args.discovery_url}: server returned {discovery_file.status}",
                 file=sys.stderr,
             print(
                 f"error getting {args.discovery_url}: server returned {discovery_file.status}",
                 file=sys.stderr,
@@ -326,8 +338,8 @@ def main(arglist: Optional[Sequence[str]]=None) -> int:
         discovery_document = json.load(discovery_file)
     print(
         to_docstring(_MODULE_PYDOC, indent=0),
         discovery_document = json.load(discovery_file)
     print(
         to_docstring(_MODULE_PYDOC, indent=0),
-        '''from typing import Any, TypedDict''',
-        sep='\n\n', end='\n\n', file=args.out_file,
+        _MODULE_PRELUDE,
+        sep='\n', file=args.out_file,
     )
 
     schemas = sorted(discovery_document['schemas'].items())
     )
 
     schemas = sorted(discovery_document['schemas'].items())
@@ -353,6 +365,7 @@ def main(arglist: Optional[Sequence[str]]=None) -> int:
         }
         print(Method(name, method_spec).doc(), file=args.out_file)
 
         }
         print(Method(name, method_spec).doc(), file=args.out_file)
 
+    args.out_file.close()
     return os.EX_OK
 
 if __name__ == '__main__':
     return os.EX_OK
 
 if __name__ == '__main__':