##// END OF EJS Templates
ignore some traitlets types
Matthias Bussonnier -
Show More
@@ -1,161 +1,156 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for managing IPython history.
3 An application for managing IPython history.
4
4
5 To be invoked as the `ipython history` subcommand.
5 To be invoked as the `ipython history` subcommand.
6 """
6 """
7
7
8 import sqlite3
8 import sqlite3
9 from pathlib import Path
9 from pathlib import Path
10
10
11 from traitlets.config.application import Application
11 from traitlets.config.application import Application
12 from .application import BaseIPythonApplication
12 from .application import BaseIPythonApplication
13 from traitlets import Bool, Int, Dict
13 from traitlets import Bool, Int, Dict
14 from ..utils.io import ask_yes_no
14 from ..utils.io import ask_yes_no
15
15
16 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
16 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
17
17
18 This actually copies the last 1000 entries to a new database, and then replaces
18 This actually copies the last 1000 entries to a new database, and then replaces
19 the old file with the new. Use the `--keep=` argument to specify a number
19 the old file with the new. Use the `--keep=` argument to specify a number
20 other than 1000.
20 other than 1000.
21 """
21 """
22
22
23 clear_hist_help = """Clear the IPython history database, deleting all entries.
23 clear_hist_help = """Clear the IPython history database, deleting all entries.
24
24
25 Because this is a destructive operation, IPython will prompt the user if they
25 Because this is a destructive operation, IPython will prompt the user if they
26 really want to do this. Passing a `-f` flag will force clearing without a
26 really want to do this. Passing a `-f` flag will force clearing without a
27 prompt.
27 prompt.
28
28
29 This is an handy alias to `ipython history trim --keep=0`
29 This is an handy alias to `ipython history trim --keep=0`
30 """
30 """
31
31
32
32
33 class HistoryTrim(BaseIPythonApplication):
33 class HistoryTrim(BaseIPythonApplication):
34 description = trim_hist_help
34 description = trim_hist_help
35
36 backup = Bool(False,
37 help="Keep the old history file as history.sqlite.<N>"
38 ).tag(config=True)
39
40 keep = Int(1000,
41 help="Number of recent lines to keep in the database."
42 ).tag(config=True)
43
44 flags = Dict(dict(
45 backup = ({'HistoryTrim' : {'backup' : True}},
46 backup.help
47 )
48 ))
49
35
50 aliases=Dict(dict(
36 backup = Bool(False, help="Keep the old history file as history.sqlite.<N>").tag(
51 keep = 'HistoryTrim.keep'
37 config=True
52 ))
38 )
53
39
40 keep = Int(1000, help="Number of recent lines to keep in the database.").tag(
41 config=True
42 )
43
44 flags = Dict( # type: ignore
45 dict(backup=({"HistoryTrim": {"backup": True}}, backup.help))
46 )
47
48 aliases = Dict(dict(keep="HistoryTrim.keep")) # type: ignore
49
54 def start(self):
50 def start(self):
55 profile_dir = Path(self.profile_dir.location)
51 profile_dir = Path(self.profile_dir.location)
56 hist_file = profile_dir / "history.sqlite"
52 hist_file = profile_dir / "history.sqlite"
57 con = sqlite3.connect(hist_file)
53 con = sqlite3.connect(hist_file)
58
54
59 # Grab the recent history from the current database.
55 # Grab the recent history from the current database.
60 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
56 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
61 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
57 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
62 if len(inputs) <= self.keep:
58 if len(inputs) <= self.keep:
63 print("There are already at most %d entries in the history database." % self.keep)
59 print("There are already at most %d entries in the history database." % self.keep)
64 print("Not doing anything. Use --keep= argument to keep fewer entries")
60 print("Not doing anything. Use --keep= argument to keep fewer entries")
65 return
61 return
66
62
67 print("Trimming history to the most recent %d entries." % self.keep)
63 print("Trimming history to the most recent %d entries." % self.keep)
68
64
69 inputs.pop() # Remove the extra element we got to check the length.
65 inputs.pop() # Remove the extra element we got to check the length.
70 inputs.reverse()
66 inputs.reverse()
71 if inputs:
67 if inputs:
72 first_session = inputs[0][0]
68 first_session = inputs[0][0]
73 outputs = list(con.execute('SELECT session, line, output FROM '
69 outputs = list(con.execute('SELECT session, line, output FROM '
74 'output_history WHERE session >= ?', (first_session,)))
70 'output_history WHERE session >= ?', (first_session,)))
75 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
71 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
76 'sessions WHERE session >= ?', (first_session,)))
72 'sessions WHERE session >= ?', (first_session,)))
77 con.close()
73 con.close()
78
74
79 # Create the new history database.
75 # Create the new history database.
80 new_hist_file = profile_dir / "history.sqlite.new"
76 new_hist_file = profile_dir / "history.sqlite.new"
81 i = 0
77 i = 0
82 while new_hist_file.exists():
78 while new_hist_file.exists():
83 # Make sure we don't interfere with an existing file.
79 # Make sure we don't interfere with an existing file.
84 i += 1
80 i += 1
85 new_hist_file = profile_dir / ("history.sqlite.new" + str(i))
81 new_hist_file = profile_dir / ("history.sqlite.new" + str(i))
86 new_db = sqlite3.connect(new_hist_file)
82 new_db = sqlite3.connect(new_hist_file)
87 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
83 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
88 primary key autoincrement, start timestamp,
84 primary key autoincrement, start timestamp,
89 end timestamp, num_cmds integer, remark text)""")
85 end timestamp, num_cmds integer, remark text)""")
90 new_db.execute("""CREATE TABLE IF NOT EXISTS history
86 new_db.execute("""CREATE TABLE IF NOT EXISTS history
91 (session integer, line integer, source text, source_raw text,
87 (session integer, line integer, source text, source_raw text,
92 PRIMARY KEY (session, line))""")
88 PRIMARY KEY (session, line))""")
93 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
89 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
94 (session integer, line integer, output text,
90 (session integer, line integer, output text,
95 PRIMARY KEY (session, line))""")
91 PRIMARY KEY (session, line))""")
96 new_db.commit()
92 new_db.commit()
97
93
98
94
99 if inputs:
95 if inputs:
100 with new_db:
96 with new_db:
101 # Add the recent history into the new database.
97 # Add the recent history into the new database.
102 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
98 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
103 new_db.executemany('insert into history values (?,?,?,?)', inputs)
99 new_db.executemany('insert into history values (?,?,?,?)', inputs)
104 new_db.executemany('insert into output_history values (?,?,?)', outputs)
100 new_db.executemany('insert into output_history values (?,?,?)', outputs)
105 new_db.close()
101 new_db.close()
106
102
107 if self.backup:
103 if self.backup:
108 i = 1
104 i = 1
109 backup_hist_file = profile_dir / ("history.sqlite.old.%d" % i)
105 backup_hist_file = profile_dir / ("history.sqlite.old.%d" % i)
110 while backup_hist_file.exists():
106 while backup_hist_file.exists():
111 i += 1
107 i += 1
112 backup_hist_file = profile_dir / ("history.sqlite.old.%d" % i)
108 backup_hist_file = profile_dir / ("history.sqlite.old.%d" % i)
113 hist_file.rename(backup_hist_file)
109 hist_file.rename(backup_hist_file)
114 print("Backed up longer history file to", backup_hist_file)
110 print("Backed up longer history file to", backup_hist_file)
115 else:
111 else:
116 hist_file.unlink()
112 hist_file.unlink()
117
113
118 new_hist_file.rename(hist_file)
114 new_hist_file.rename(hist_file)
119
115
116
120 class HistoryClear(HistoryTrim):
117 class HistoryClear(HistoryTrim):
121 description = clear_hist_help
118 description = clear_hist_help
122 keep = Int(0,
119 keep = Int(0, help="Number of recent lines to keep in the database.")
123 help="Number of recent lines to keep in the database.")
120
124
121 force = Bool(False, help="Don't prompt user for confirmation").tag(config=True)
125 force = Bool(False,
122
126 help="Don't prompt user for confirmation"
123 flags = Dict( # type: ignore
127 ).tag(config=True)
124 dict(
128
125 force=({"HistoryClear": {"force": True}}, force.help),
129 flags = Dict(dict(
126 f=({"HistoryTrim": {"force": True}}, force.help),
130 force = ({'HistoryClear' : {'force' : True}},
131 force.help),
132 f = ({'HistoryTrim' : {'force' : True}},
133 force.help
134 )
127 )
135 ))
128 )
136 aliases = Dict()
129 aliases = Dict() # type: ignore
137
130
138 def start(self):
131 def start(self):
139 if self.force or ask_yes_no("Really delete all ipython history? ",
132 if self.force or ask_yes_no(
140 default="no", interrupt="no"):
133 "Really delete all ipython history? ", default="no", interrupt="no"
134 ):
141 HistoryTrim.start(self)
135 HistoryTrim.start(self)
142
136
137
143 class HistoryApp(Application):
138 class HistoryApp(Application):
144 name = u'ipython-history'
139 name = "ipython-history"
145 description = "Manage the IPython history database."
140 description = "Manage the IPython history database."
146
141
147 subcommands = Dict(dict(
142 subcommands = Dict(dict(
148 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
143 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
149 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
144 clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
150 ))
145 ))
151
146
152 def start(self):
147 def start(self):
153 if self.subapp is None:
148 if self.subapp is None:
154 print("No subcommand specified. Must specify one of: %s" % \
149 print("No subcommand specified. Must specify one of: %s" % \
155 (self.subcommands.keys()))
150 (self.subcommands.keys()))
156 print()
151 print()
157 self.print_description()
152 self.print_description()
158 self.print_subcommands()
153 self.print_subcommands()
159 self.exit(1)
154 self.exit(1)
160 else:
155 else:
161 return self.subapp.start()
156 return self.subapp.start()
@@ -1,87 +1,84 b''
1 [build-system]
1 [build-system]
2 requires = ["setuptools >= 51.0.0"]
2 requires = ["setuptools >= 51.0.0"]
3 # We need access to the 'setupbase' module at build time.
3 # We need access to the 'setupbase' module at build time.
4 # Hence we declare a custom build backend.
4 # Hence we declare a custom build backend.
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
5 build-backend = "_build_meta" # just re-exports setuptools.build_meta definitions
6 backend-path = ["."]
6 backend-path = ["."]
7
7
8 [tool.mypy]
8 [tool.mypy]
9 python_version = "3.10"
9 python_version = "3.10"
10 ignore_missing_imports = true
10 ignore_missing_imports = true
11 follow_imports = 'silent'
11 follow_imports = 'silent'
12 exclude = [
12 exclude = [
13 'test_\.+\.py',
13 'test_\.+\.py',
14 'IPython.utils.tests.test_wildcard',
14 'IPython.utils.tests.test_wildcard',
15 'testing',
15 'testing',
16 'tests',
16 'tests',
17 'PyColorize.py',
17 'PyColorize.py',
18 '_process_win32_controller.py',
18 '_process_win32_controller.py',
19 'IPython/core/application.py',
19 'IPython/core/application.py',
20 'IPython/core/completerlib.py',
20 'IPython/core/completerlib.py',
21 'IPython/core/displaypub.py',
21 'IPython/core/displaypub.py',
22 'IPython/core/historyapp.py',
23 #'IPython/core/interactiveshell.py',
22 #'IPython/core/interactiveshell.py',
24 'IPython/core/magic.py',
23 'IPython/core/magic.py',
25 'IPython/core/profileapp.py',
24 'IPython/core/profileapp.py',
26 # 'IPython/core/ultratb.py',
25 # 'IPython/core/ultratb.py',
27 'IPython/lib/deepreload.py',
26 'IPython/lib/deepreload.py',
28 'IPython/lib/pretty.py',
27 'IPython/lib/pretty.py',
29 'IPython/sphinxext/ipython_directive.py',
28 'IPython/sphinxext/ipython_directive.py',
30 'IPython/terminal/ipapp.py',
29 'IPython/terminal/ipapp.py',
31 'IPython/utils/_process_win32.py',
30 'IPython/utils/_process_win32.py',
32 'IPython/utils/path.py',
31 'IPython/utils/path.py',
33 'IPython/utils/timing.py',
34 'IPython/utils/text.py'
35 ]
32 ]
36
33
37 [tool.pytest.ini_options]
34 [tool.pytest.ini_options]
38 addopts = [
35 addopts = [
39 "--durations=10",
36 "--durations=10",
40 "-pIPython.testing.plugin.pytest_ipdoctest",
37 "-pIPython.testing.plugin.pytest_ipdoctest",
41 "--ipdoctest-modules",
38 "--ipdoctest-modules",
42 "--ignore=docs",
39 "--ignore=docs",
43 "--ignore=examples",
40 "--ignore=examples",
44 "--ignore=htmlcov",
41 "--ignore=htmlcov",
45 "--ignore=ipython_kernel",
42 "--ignore=ipython_kernel",
46 "--ignore=ipython_parallel",
43 "--ignore=ipython_parallel",
47 "--ignore=results",
44 "--ignore=results",
48 "--ignore=tmp",
45 "--ignore=tmp",
49 "--ignore=tools",
46 "--ignore=tools",
50 "--ignore=traitlets",
47 "--ignore=traitlets",
51 "--ignore=IPython/core/tests/daft_extension",
48 "--ignore=IPython/core/tests/daft_extension",
52 "--ignore=IPython/sphinxext",
49 "--ignore=IPython/sphinxext",
53 "--ignore=IPython/terminal/pt_inputhooks",
50 "--ignore=IPython/terminal/pt_inputhooks",
54 "--ignore=IPython/__main__.py",
51 "--ignore=IPython/__main__.py",
55 "--ignore=IPython/external/qt_for_kernel.py",
52 "--ignore=IPython/external/qt_for_kernel.py",
56 "--ignore=IPython/html/widgets/widget_link.py",
53 "--ignore=IPython/html/widgets/widget_link.py",
57 "--ignore=IPython/html/widgets/widget_output.py",
54 "--ignore=IPython/html/widgets/widget_output.py",
58 "--ignore=IPython/terminal/console.py",
55 "--ignore=IPython/terminal/console.py",
59 "--ignore=IPython/utils/_process_cli.py",
56 "--ignore=IPython/utils/_process_cli.py",
60 "--ignore=IPython/utils/_process_posix.py",
57 "--ignore=IPython/utils/_process_posix.py",
61 "--ignore=IPython/utils/_process_win32.py",
58 "--ignore=IPython/utils/_process_win32.py",
62 "--ignore=IPython/utils/_process_win32_controller.py",
59 "--ignore=IPython/utils/_process_win32_controller.py",
63 "--ignore=IPython/utils/daemonize.py",
60 "--ignore=IPython/utils/daemonize.py",
64 "--ignore=IPython/utils/eventful.py",
61 "--ignore=IPython/utils/eventful.py",
65 "--ignore=IPython/kernel",
62 "--ignore=IPython/kernel",
66 "--ignore=IPython/consoleapp.py",
63 "--ignore=IPython/consoleapp.py",
67 "--ignore=IPython/core/inputsplitter.py",
64 "--ignore=IPython/core/inputsplitter.py",
68 "--ignore=IPython/lib/kernel.py",
65 "--ignore=IPython/lib/kernel.py",
69 "--ignore=IPython/utils/jsonutil.py",
66 "--ignore=IPython/utils/jsonutil.py",
70 "--ignore=IPython/utils/localinterfaces.py",
67 "--ignore=IPython/utils/localinterfaces.py",
71 "--ignore=IPython/utils/log.py",
68 "--ignore=IPython/utils/log.py",
72 "--ignore=IPython/utils/signatures.py",
69 "--ignore=IPython/utils/signatures.py",
73 "--ignore=IPython/utils/traitlets.py",
70 "--ignore=IPython/utils/traitlets.py",
74 "--ignore=IPython/utils/version.py"
71 "--ignore=IPython/utils/version.py"
75 ]
72 ]
76 doctest_optionflags = [
73 doctest_optionflags = [
77 "NORMALIZE_WHITESPACE",
74 "NORMALIZE_WHITESPACE",
78 "ELLIPSIS"
75 "ELLIPSIS"
79 ]
76 ]
80 ipdoctest_optionflags = [
77 ipdoctest_optionflags = [
81 "NORMALIZE_WHITESPACE",
78 "NORMALIZE_WHITESPACE",
82 "ELLIPSIS"
79 "ELLIPSIS"
83 ]
80 ]
84 asyncio_mode = "strict"
81 asyncio_mode = "strict"
85
82
86 [tool.pyright]
83 [tool.pyright]
87 pythonPlatform="All"
84 pythonPlatform="All"
General Comments 0
You need to be logged in to leave comments. Login now