sassoftware / saspy

A Python interface module to the SAS System. It works with Linux, Windows, and Mainframe SAS as well as with SAS in Viya.
https://sassoftware.github.io/saspy
Other
367 stars 149 forks source link

SASsessionIOM()._endsas() generates 3 x ResourceWarning: unclosed file #489

Closed jonaswvd closed 1 year ago

jonaswvd commented 1 year ago

Running saspy 4.3.3 with local SAS 9.4 windows installation generates 3 ResourceWarnings: python example_file.py -Walways

example_file.py:

import saspy

with saspy.SASsession(cfgfile="sascfg_personal.py", cfgname="winlocal") as sas:
    pass

sascfg_personal.py:

import os

os.environ["PATH"] += ";C:\\Program Files\\SAS 9.4\\SASFoundation\\9.4\\core\\sasext"

SAS_config_names = ["winlocal"]

winlocal = {"java": r"C:\Program Files (x86)\Common Files\Oracle\Java\javapath\java.exe", "encoding": "windows-1252"}

Print of ResourceWarningns and setup info generated by running following (using PYTHONTRACEMALLOC=1 for tracing where unclosed files are opened); python print_stuff.py -Walways PYTHONTRACEMALLOC=1

print_stuff.py

import saspy

print(saspy)
print(saspy.SAScfg)
print(saspy.list_configs())

with saspy.SASsession(cfgfile="sascfg_personal.py", cfgname="winlocal") as sas:
    print(sas)

prints:

<module 'saspy' from 'C:\\ProgramData\\AnacondaTeamEdition\\envs\\dev_scr\\lib\\site-packages\\saspy\\__init__.py'>
C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\site-packages\saspy\sascfg.py
['C:\\ProgramData\\AnacondaTeamEdition\\envs\\dev_scr\\lib\\site-packages\\saspy\\sascfg.py']
SAS Connection established. Subprocess id is 4744

Access Method         = IOM
SAS Config name       = winlocal
SAS Config file       = C:\Users\BE0096\Repo\scr2\drm_scr\sascfg_personal.py
WORK Path             = C:\Users\BE0096\AppData\Local\Temp\SAS Temporary Files\_TD22144_WP6258_\Prc2\
SAS Version           = 9.04.01M6P11072018
SASPy Version         = 4.3.3
Teach me SAS          = False
Batch                 = False
Results               = Pandas
SAS Session Encoding  = wlatin1
Python Encoding value = windows-1252
SAS process Pid value = 22144

C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\site-packages\saspy\sasioiom.py:572: ResourceWarning: unclosed file <_io.BufferedWriter name=4>
  self.pid = None
Object allocated at (most recent call last):
  File "C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\subprocess.py", lineno 935
    self.stdin = io.open(p2cwrite, 'wb', bufsize)
C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\site-packages\saspy\sasioiom.py:572: ResourceWarning: unclosed file <_io.BufferedReader name=5>
  self.pid = None
Object allocated at (most recent call last):
  File "C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\subprocess.py", lineno 941
    self.stdout = io.open(c2pread, 'rb', bufsize)
C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\site-packages\saspy\sasioiom.py:572: ResourceWarning: unclosed file <_io.BufferedReader name=6>
  self.pid = None
Object allocated at (most recent call last):
  File "C:\ProgramData\AnacondaTeamEdition\envs\dev_scr\lib\subprocess.py", lineno 946
    self.stderr = io.open(errread, 'rb', bufsize)
SAS Connection terminated. Subprocess id was 4744

Specifically the line:

self.pid = None

in SASsessionIOM()._endsas() generates the 3 x ResourceWarnings.

Can be fixed by inserting:

self.pid.communicate()

or

self.pid.stdin.close()
self.pid.stdout.close()
self.pid.stderr.close()

just before self.pid = None.

tomweber-sas commented 1 year ago

Hey, thanks for providing this. I see that it's only from the windows client side where I have to use that Popen function since the OS level functions aren't there on windows; fork/exec/...

And, I see it's the pipes that are what weren't being closed; they aren't used as I have sockets for communication with my subprocess (java in the IOM case). I wasn't able to reproduce what you posted, exactly, but I saw some similar messages when running some of this with unittest. So that let me better see what I was missing; seeing it was the unused pipes. I also had one occurance of this in my STDIO access method, since that is now supported from a windows client (only for SSH), so I fixed that case similarly.

I just pushed changes to the main branch to address this. Since I wasn't seeing the same thing you were, can you pull from main and run your test case again and see if I've address what you are seeing? Here's the easy way to get this:

pip uninstall -y saspy pip install git+https://git@github.com/sassoftware/saspy.git

Thanks! Tom

jonaswvd commented 1 year ago

That seems to have done the trick, thank you!

tomweber-sas commented 1 year ago

Fantastic, and thanks for finding that. Guess we can close this. This will be incorporated in the next release I publish. But for now, you should be good with this. Thanks! Tom