annotate hgext/convert/transport.py @ 41417:5c73441a47e5

crecord: always return a str from uihunk.__repr__ Otherwise Python 3 complains about it returning bytes. Differential Revision: https://phab.mercurial-scm.org/D5728
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 26 Jan 2019 16:45:25 -0800
parents ffb30661f672
children 2372284d9457
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
2
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
3 # Copyright (C) 2007 Daniel Holth <dholth@fastmail.fm>
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
4 # This is a stripped-down version of the original bzr-svn transport.py,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
5 # Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
6
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
7 # This program is free software; you can redistribute it and/or modify
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
8 # it under the terms of the GNU General Public License as published by
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
9 # the Free Software Foundation; either version 2 of the License, or
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
10 # (at your option) any later version.
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
11
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
15 # GNU General Public License for more details.
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
16
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
17 # You should have received a copy of the GNU General Public License
15782
7de7630053cb Remove FSF mailing address from GPL headers
Martin Geisler <mg@aragost.com>
parents: 15599
diff changeset
18 # along with this program; if not, see <http://www.gnu.org/licenses/>.
28412
1e03b74195d4 convert: transport use absolute_import
timeless <timeless@mozdev.org>
parents: 25660
diff changeset
19 from __future__ import absolute_import
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
20
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
21 import svn.client
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
22 import svn.core
28412
1e03b74195d4 convert: transport use absolute_import
timeless <timeless@mozdev.org>
parents: 25660
diff changeset
23 import svn.ra
1e03b74195d4 convert: transport use absolute_import
timeless <timeless@mozdev.org>
parents: 25660
diff changeset
24
1e03b74195d4 convert: transport use absolute_import
timeless <timeless@mozdev.org>
parents: 25660
diff changeset
25 Pool = svn.core.Pool
1e03b74195d4 convert: transport use absolute_import
timeless <timeless@mozdev.org>
parents: 25660
diff changeset
26 SubversionException = svn.core.SubversionException
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
27
28461
b433233e25d9 convert: fix "stdlib import follows local import" problem in transport
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28412
diff changeset
28 from mercurial import (
b433233e25d9 convert: fix "stdlib import follows local import" problem in transport
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28412
diff changeset
29 util,
b433233e25d9 convert: fix "stdlib import follows local import" problem in transport
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28412
diff changeset
30 )
b433233e25d9 convert: fix "stdlib import follows local import" problem in transport
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28412
diff changeset
31
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4938
diff changeset
32 # Some older versions of the Python bindings need to be
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
33 # explicitly initialized. But what we want to do probably
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
34 # won't work worth a darn against those libraries anyway!
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
35 svn.ra.initialize()
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
36
29668
09a5699cc3cb convert: move svn config initializer out of the module level
Durham Goode <durham@fb.com>
parents: 28461
diff changeset
37 svn_config = None
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
38
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
39 def _create_auth_baton(pool):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
40 """Create a Subversion authentication baton. """
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
41 import svn.client
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
42 # Give the client context baton a suite of authentication
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
43 # providers.h
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
44 providers = [
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
45 svn.client.get_simple_provider(pool),
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
46 svn.client.get_username_provider(pool),
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
47 svn.client.get_ssl_client_cert_file_provider(pool),
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
48 svn.client.get_ssl_client_cert_pw_file_provider(pool),
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
49 svn.client.get_ssl_server_trust_file_provider(pool),
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
50 ]
17481
b555be7ca830 spelling: dependent
timeless@mozdev.org
parents: 15782
diff changeset
51 # Platform-dependent authentication methods
8120
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
52 getprovider = getattr(svn.core, 'svn_auth_get_platform_specific_provider',
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
53 None)
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
54 if getprovider:
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
55 # Available in svn >= 1.6
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
56 for name in ('gnome_keyring', 'keychain', 'kwallet', 'windows'):
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
57 for type in ('simple', 'ssl_client_cert_pw', 'ssl_server_trust'):
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
58 p = getprovider(name, type, pool)
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
59 if p:
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
60 providers.append(p)
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
61 else:
14945
11aad09a6370 hgext: replace uses of hasattr with util.safehasattr
Augie Fackler <durin42@gmail.com>
parents: 11498
diff changeset
62 if util.safehasattr(svn.client, 'get_windows_simple_provider'):
8120
2b36ed5c1911 convert/svn: support more OS specific auth providers via svn 1.6 API
Patrick Mezard <pmezard@gmail.com>
parents: 6215
diff changeset
63 providers.append(svn.client.get_windows_simple_provider(pool))
5126
117dab48ca99 convert: support windows SVN simple auth provider
Patrick Mezard <pmezard@gmail.com>
parents: 4957
diff changeset
64
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
65 return svn.core.svn_auth_open(providers, pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
66
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
67 class NotBranchError(SubversionException):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
68 pass
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
69
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
70 class SvnRaTransport(object):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
71 """
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
72 Open an ra connection to a Subversion repository.
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
73 """
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
74 def __init__(self, url="", ra=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
75 self.pool = Pool()
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
76 self.svn_url = url
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
77 self.username = ''
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
78 self.password = ''
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
79
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
80 # Only Subversion 1.4 has reparent()
14945
11aad09a6370 hgext: replace uses of hasattr with util.safehasattr
Augie Fackler <durin42@gmail.com>
parents: 11498
diff changeset
81 if ra is None or not util.safehasattr(svn.ra, 'reparent'):
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
82 self.client = svn.client.create_context(self.pool)
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
83 ab = _create_auth_baton(self.pool)
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
84 self.client.auth_baton = ab
29668
09a5699cc3cb convert: move svn config initializer out of the module level
Durham Goode <durham@fb.com>
parents: 28461
diff changeset
85 global svn_config
09a5699cc3cb convert: move svn config initializer out of the module level
Durham Goode <durham@fb.com>
parents: 28461
diff changeset
86 if svn_config is None:
09a5699cc3cb convert: move svn config initializer out of the module level
Durham Goode <durham@fb.com>
parents: 28461
diff changeset
87 svn_config = svn.core.svn_config_get_config(None)
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
88 self.client.config = svn_config
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
89 try:
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
90 self.ra = svn.client.open_ra_session(
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15345
diff changeset
91 self.svn_url,
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
92 self.client, self.pool)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 17481
diff changeset
93 except SubversionException as xxx_todo_changeme:
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 17481
diff changeset
94 (inst, num) = xxx_todo_changeme.args
4938
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
95 if num in (svn.core.SVN_ERR_RA_ILLEGAL_URL,
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
96 svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED,
4db03fa58bd5 convert/subversion: get converter working against plain HTTP.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4764
diff changeset
97 svn.core.SVN_ERR_BAD_URL):
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
98 raise NotBranchError(url)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
99 raise
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
100 else:
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
101 self.ra = ra
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
102 svn.ra.reparent(self.ra, self.svn_url.encode('utf8'))
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
103
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8120
diff changeset
104 class Reporter(object):
11498
8fa85378c527 convert: tuple parameter unpacking is deprecated in py3k
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
105 def __init__(self, reporter_data):
8fa85378c527 convert: tuple parameter unpacking is deprecated in py3k
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
106 self._reporter, self._baton = reporter_data
4764
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
107
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
108 def set_path(self, path, revnum, start_empty, lock_token, pool=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
109 svn.ra.reporter2_invoke_set_path(self._reporter, self._baton,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
110 path, revnum, start_empty, lock_token, pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
111
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
112 def delete_path(self, path, pool=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
113 svn.ra.reporter2_invoke_delete_path(self._reporter, self._baton,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
114 path, pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
115
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
116 def link_path(self, path, url, revision, start_empty, lock_token,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
117 pool=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
118 svn.ra.reporter2_invoke_link_path(self._reporter, self._baton,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
119 path, url, revision, start_empty, lock_token,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
120 pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
121
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
122 def finish_report(self, pool=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
123 svn.ra.reporter2_invoke_finish_report(self._reporter,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
124 self._baton, pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
125
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
126 def abort_report(self, pool=None):
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
127 svn.ra.reporter2_invoke_abort_report(self._reporter,
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
128 self._baton, pool)
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
129
6a16ef0d1c7c convert extension: stripped-down svn transport module
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
130 def do_update(self, revnum, path, *args, **kwargs):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
131 return self.Reporter(svn.ra.do_update(self.ra, revnum, path,
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
132 *args, **kwargs))