1

I am trying to write a file transfer program and trying to make a list of files to skip processing: The script itself, and the VI backup and swap files (server.py~ and .server.py.swp)

I cannot get the proper name of the vi swap file, .server.py.swp, the dot at the beginning is missing and I get server.py.swp

I first create the list with .server.py.swp hardcoded (I had the others hardcoded, but removed them after I got the string formatting for them working). I then add the script file and backup file using string formatting. I append string "test" for debugging purposes and as a separator. Finally, I try to add the swap file with string formatting using two different methods and it gets added with the leading . at the front missing.

To run the code in server.py I am referring to, I have a client.py I am in the process of developing.

client.py

import os, socket
port = 7777
host = socket.gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

server.py

import os, socket

port = 7777
host = socket.gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)

while True:
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!!!")
    # https://stackoverflow.com/questions/4934806
    File = os.path.realpath(__file__)
    dir = os.path.dirname(File)
    os.chdir(dir)
    server_files = os.listdir(".")
    skip = [".server.py.swp"]
    # https://pythonguides.com/python-get-filename-from-the-path/
    skip.append(os.path.basename(File))
    skip.append(os.path.basename(f"{File}~"))
    skip.append(f"test")
    skip.append(os.path.basename(f".{File}.swp"))
    skip.append(os.path.basename(".{}.swp".format(File)))
    print(f"Skip:   {skip}")

# !End

I get incorrect output on the server

Skip: ['.server.py.swp', 'server.py', 'server.py~', 'test', 'server.py.swp', 'server.py.swp']

My desired output would be something like

Skip: ['.server.py.swp', 'server.py', 'server.py~', 'test', '.server.py.swp', '.server.py.swp']

Am I missing something? I tried escaping the . by putting in \. to no avail.

EDIT: I aim for this to be cross-platform, but for now I am developing and testing this one on Windows.

  • Now's a good time to learn [how to debug small programs.](//ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [what is a debugger and how can it help me diagnose problems?](//stackoverflow.com/q/25385173/843953) Step through your code and observe what each line of code does. Identify where your program differs from your expectations by comparing these intermediate results with expected results. What are the contents of `File`? (I suspect absolute path to `server.py`) What do you get from `f".{File}.swp"`? What do you expect `basename` to do to that string? – Pranav Hosangadi Apr 07 '21 at 21:38
  • I test the code and it is working on my machine. Im runnind Debian 10 with pyhon 3.7.3. What is your python version and the OS? + Why do you need the os.path.basename, because the base name. Remove the os.path.basename stuff and just add the filename – ThunderHorn Apr 07 '21 at 21:46
  • Did you downvote my question, why? Thanks, I'll look at those links. ` Step through your code and observe what each line of code does. Identify where your program differs from your expectations by comparing these intermediate results with expected results.` that's what I am trying to do. `What are the contents of File` `What do you get from f".{File}.swp"` , can't you tell from the list? Yes, I am trying to get absolute path of the script and filenames without path, regardless of whether the script was run using an absolute or relative path. Am I not doing this correctly?Is there a better way? – Operation420.net Apr 07 '21 at 21:49
  • @ThunderHorn, oh sorry I forgot to mention, Windows 10 – Operation420.net Apr 07 '21 at 21:49
  • @Operation420.net Did you try to run the string formatting in separate file just to test if it is working + you can do another string formatt `".%s.swp" % File` and add it to the test collection – ThunderHorn Apr 07 '21 at 21:53
  • @Operation420.net What is your python version – ThunderHorn Apr 07 '21 at 21:53
  • @Operation420.net I'd like _you_ to ask yourself those questions and answer them. Follow through the train of thought and see if the code you have written will do what you actually want it to do. What happens if you do `f".{File}.swp"` where `File` is an absolute path (`C:\something\server.py`)? Do you get the path to `.server.py.swp`, or do you get something else that you did not expect? What do you think `basepath` will return with that argument? Figuring out how to fix your problem is fairly easy if you understand why it happens! – Pranav Hosangadi Apr 07 '21 at 21:54
  • 1
    ```>>> f".{File}.swp" '.C:\\something\\server.py.swp'``` Oh I see, the dot is getting appended before the full path. I suspected basepath might have been the culprit but wasn't sure how. I usually would have – Operation420.net Apr 07 '21 at 22:00
  • done something like `File = os.path.basename(File)` then `skip.append(File)` `skip.append("{}~".format(File))` But was trying not to overwrite the variables and use as few lines of code as possible, but perhaps I am not ready yet.. – Operation420.net Apr 07 '21 at 22:03
  • _There you go!_ I apologize if my previous comments seemed brusque, but while debugging it's very important to ensure your code does what you think it is doing and to trace any problems back. Something wrong with thr output of `basename`? Hmm, let me see what inputs I give it. Are those inputs correct? No? Where did _they_ come from? And so on... – Pranav Hosangadi Apr 07 '21 at 22:04
  • Yes, I have to look more at what basename does, I just looked it up today – Operation420.net Apr 07 '21 at 22:07
  • @ThunderHorn, it's resolved now but for what it's worth: `Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on win32` – Operation420.net Apr 07 '21 at 22:39

1 Answers1

2

Given that File appears to be a qualified path, not just a file name, prefixing with . before calling basename does nothing; if File is C:\foo\bar.py (would print with extra \s) or /foo/bar.py or even ../relative/bar.py, prefixing with a . puts it before the final directory separator (\ or /), and it gets stripped by basename. If you want to prefix the file name with ., add it after stripping directories, e.g.:

skip.append("." + os.path.basename(f"{File}.swp"))

or

skip.append(".{}.swp".format(os.path.basename(File)))
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Thanks. I am trying to learn fstrings, sockets, and pathutils all at once. Previously I worked with paths using "".split but working with different OSes and backslashes in strings when using Windows wasn't pretty and I figured there had to better way. – Operation420.net Apr 07 '21 at 22:24
  • @Operation420.net: If you're learning from scratch, I'd [recommend `pathlib`](https://docs.python.org/3/library/pathlib.html) for this purpose. `File = pathlib.Path(__file__)`, then compute a modified form with `f".{File.name}.swp"` or the like. OO paths are nice. You can even make a new full path object, referring to the same directory, with `File.with_name(f".{File.name}.swp")`, which makes a new `Path` with the same information (e.g. known path) just tweaking the file name. `pathlib` makes a lot of stuff nicer, e.g. `.name`/`.parent` for `basename`/`dirname`, `/` overloaded to join, etc. – ShadowRanger Apr 07 '21 at 22:32