pythonwindowscondacommand-history

write_history_file("pyHistory"): 'str' object has no attribute 'mode'


I am following this answer on writing the Python command history to a file, which relies on the readline module and the write_history_file function therein. I have to account for differences in using the Conda prompt on Windows 10, which is just the CMD prompt with environment variables set fo Conda. For this use case there is no history file in c:\User.Name, which is typically the case. Additionally, I need pyreadline3.

Here is how I found the "module path" to write_history_file in pyreadline3:

from pprint import pprint
import inspect, pyreadline3
pprint(inspect.getmembers(pyreadline3.Readline))

   <...snip...>
   ('write_history_file',
    <function BaseReadline.write_history_file at 0x000001D67D83D280>)]^M^[[25l
   <...snip...>

There are some puzzling terminal-oriented control characters because I used Cygwin's Bash and typescript to launch Conda (see here), but the "path" is shown to be BaseReadline.write_history_file. I got the syntax of write_history_file from this answer. Here is how I used it, resulting in an "AttributeError":

>>> pyreadline3.BaseReadline.write_history_file('pyHistory')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\User.Name\.conda\envs\py39\lib\site-packages\pyreadline3\rlmain.p y",
             line 180, in write_history_file
    self.mode._history.write_history_file(filename)
AttributeError: 'str' object has no attribute 'mode'

I get the same AttributeError even if I adorn the file name pyHistory with double-quotations. The only thing I can find on the above AttributeError error is this Q&A but it doesn't seem to be applicable because the answer there is that the wrong type of argument is being supplied.

How else can track down the cause of this error?

For me, the simpler the better. I am trying to access a live command history because it helps me experiment and get started with Python (and Conda), coming from a Matlab where the history is always available.


Solution

  • pyreadline3 and readline are two different modules. The answer you copied that code from is for readline.write_history_file, which takes a single string as an argument.

    You're trying to call pyreadline3.BaseReadline.write_history_file, which is a different function. In fact, it's actually not a function, it's a method. So when you try to run BaseReadline.write_history_file("..."), you're passing the string "..." as the instance object self. Hence why this explodes catastrophically.

    To use that method correctly, you need to start by creating an instance of BaseReadline (or really, of an appropriate subclass, like Readline). Then you can invoke the method on that instance:

    r = pyreadline3.Readline()
    r.write_history_file("./pyHistory.txt")