...
 
Commits (5)
......@@ -4,5 +4,6 @@ recursive-include data/clcache *
recursive-include docs pyraf_tutorial.pdf pyraf_tutorial.ps.gz pyraf_install_src.ps pyraf_install_src.pdf
recursive-include lib *
recursive-include src *.h *.c
recursive-include tests *.py *.fits *.ref *.ps
recursive-include tools *.py
recursive-include required_pkgs *
Metadata-Version: 1.1
Name: pyraf
Version: 2.1.14
Version: 2.1.15
Summary: Provides a Pythonic interface to IRAF that can be used in place of the existing IRAF CL
Home-page: http://www.stsci.edu/resources/software_hardware/pyraf
Author: Rick White, Perry Greenfield, Chris Sontag
Author-email: help@stsci.edu
License: UNKNOWN
Description: PyRAF is a command language for IRAF based on the Python scripting language
Description: PyRAF
=====
.. image:: https://ssbjenkins.stsci.edu/buildStatus/icon?job=STScI/pyraf/master
:target: https://ssbjenkins.stsci.edu/job/STScI/job/pyraf/job/master/
:alt: Jenkins CI status
PyRAF is a command language for IRAF based on the Python scripting language
that can be used in place of the existing IRAF CL.
For more information on PyRAF - release notes, installation instructions,
......
PyRAF
=====
.. image:: https://ssbjenkins.stsci.edu/buildStatus/icon?job=STScI/pyraf/master
:target: https://ssbjenkins.stsci.edu/job/STScI/job/pyraf/job/master/
:alt: Jenkins CI status
PyRAF is a command language for IRAF based on the Python scripting language
that can be used in place of the existing IRAF CL.
......
# -*- Mode: Shell-Script -*- Not really, but shows comments correctly
#***************************************************************************
#
# Configuration file for ipython -- ipythonrc format
#
# The format of this file is one of 'key value' lines.
# Lines containing only whitespace at the beginning and then a # are ignored
# as comments. But comments can NOT be put on lines with data.
#***************************************************************************
# This is an example of a 'profile' file which includes a base file and adds
# some customizaton for a particular purpose.
# If this file is found in the user's ~/.ipython directory as
# ipythonrc-pyraf, it can be loaded by calling passing the '-profile
# pyraf' (or '-p pyraf') option to IPython.
# A simple alias pyraf -> 'ipython -p pyraf' makes life very convenient.
# Load the user's basic configuration
include ipythonrc
# import ...
import_mod pyraf.ipython_api
import_mod iraf
pyraf (2.1.15-1) unstable; urgency=low
* Switch watch to use pypi
* New upstream version 2.1.15. Rediff patches
* Push Standards-Versionto 4.2.0. No changes required
-- Ole Streicher <olebole@debian.org> Thu, 09 Aug 2018 14:59:41 +0200
pyraf (2.1.14+dfsg-7) unstable; urgency=low
[ Chris Lamb ]
......
......@@ -21,7 +21,7 @@ Build-Depends: debhelper (>= 11),
python3-stsci.tools,
python3-tk
Section: python
Standards-Version: 4.1.4
Standards-Version: 4.2.0
Homepage: http://www.stsci.edu/institute/software_hardware/pyraf
Vcs-Browser: https://salsa.debian.org/debian-astro-team/pyraf
Vcs-Git: https://salsa.debian.org/debian-astro-team/pyraf.git
......
From: Ole Streicher <olebole@debian.org>
Date: Wed, 20 Dec 2017 15:41:56 +0100
Subject: Remove "module" name extension from extension modules
---
setup.cfg | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/setup.cfg b/setup.cfg
index f64df66..cc23df7 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -25,12 +25,12 @@ data_files =
pyraf/clcache = data/clcache/*
scripts = scripts/pyraf
-[extension=pyraf.sscanfmodule]
+[extension=pyraf.sscanf]
sources = src/sscanfmodule.c
optional = True
fail_message = If this is Windows, it is ok.
-[extension=pyraf.xutilmodule]
+[extension=pyraf.xutil]
sources = src/xutil.c
libraries = X11
......@@ -8,10 +8,10 @@ Subject: Use system provided iraf by default
2 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/lib/pyraf/clcache.py b/lib/pyraf/clcache.py
index f47a01e..087c640 100644
index ce34c71..2f025a3 100644
--- a/lib/pyraf/clcache.py
+++ b/lib/pyraf/clcache.py
@@ -322,12 +322,10 @@ def test():
@@ -285,12 +285,10 @@ class _CodeCache:
# create code cache
......@@ -21,13 +21,13 @@ index f47a01e..087c640 100644
try:
- os.mkdir(userCacheDir)
- if '-s' not in sys.argv and '--silent' not in sys.argv:
- print 'Created directory %s for cache' % userCacheDir
- print('Created directory %s for cache' % userCacheDir)
+ os.makedirs(userCacheDir)
except OSError:
print 'Could not create directory %s' % userCacheDir
print('Could not create directory %s' % userCacheDir)
diff --git a/lib/pyraf/iraffunctions.py b/lib/pyraf/iraffunctions.py
index 63ba9ec..22f8205 100644
index 9484ad8..2cbac20 100644
--- a/lib/pyraf/iraffunctions.py
+++ b/lib/pyraf/iraffunctions.py
@@ -175,9 +175,9 @@ def Init(doprint=1,hush=0,savefile=None):
......
Use-system-provided-iraf-by-default.patch
Install-pyraf-script-only-for-Python-3.patch
Remove-module-name-extension-from-extension-modules.patch
Fix-FTBFS-for-GNU-HURD.patch
......@@ -1336,7 +1336,7 @@ def _convFunc(var, value):
else:
return str(value)
elif var.type == "int":
if value is None:
if value is None or value == "INDEF": # (matches _INDEFClass object)
return "INDEF"
elif isinstance(value,str) and value[:1] == ")":
# parameter indirection
......@@ -1344,7 +1344,7 @@ def _convFunc(var, value):
else:
return int(value)
elif var.type == "real":
if value is None:
if value is None or value == "INDEF": # (matches _INDEFClass object)
return "INDEF"
elif isinstance(value,str) and value[:1] == ")":
# parameter indirection
......@@ -2416,40 +2416,3 @@ class Tree2Python(GenericASTTraversal, ErrorTracker):
return
self.preorder(node[2])
self.prune()
if __name__ == "__main__":
import time
t0 = time.time()
# scan file "simple.cl"
filename = "simple.cl"
lines = open(filename).read()
scanner = clscan.CLScanner()
tokens = scanner.tokenize(lines)
t1 = time.time()
# parse
tree = _parser.parse(tokens, fname=filename)
tree.filename = filename
t2 = time.time()
# first pass -- get variables
vars = VarList(tree)
# second pass -- check all expression types
# type info is added to tree
TypeCheck(tree, vars, '')
# third pass -- generate python code
pycode = Tree2Python(tree, vars)
t3 = time.time()
print "Scan:", t1-t0, "sec, Parse:", t2-t1, "sec"
print "CodeGen:", t3-t2, "sec"
......@@ -4,13 +4,14 @@ $Id$
R. White, 2000 January 19
"""
from __future__ import division # confidence high
from __future__ import division, print_function # confidence high
import os, sys
import os
import sys
from stsci.tools.for2to3 import PY3K
from stsci.tools.irafglobals import Verbose, userIrafHome
if __name__.find('.') < 0: # for unit test need absolute import
if __name__.find('.') < 0: # for unit test need absolute import
for mmm in ('filecache', 'pyrafglobals', 'dirshelve'):
exec('import '+mmm, globals()) # 2to3 messes up simpler form
else:
......@@ -29,7 +30,7 @@ import copy_reg, marshal, types
try:
import cPickle as pickle
except ImportError:
import pickle
import pickle # noqa
def code_unpickler(data):
return marshal.loads(data)
......@@ -55,7 +56,7 @@ copy_reg.pickle(types.CodeType, code_pickler, code_unpickler)
# with changes of the CL file contents when the script is
# being developed.
import stat, hashlib
import hashlib
_versionKey = 'CACHE_VERSION'
......@@ -138,14 +139,14 @@ class _CodeCache:
elif fname.endswith(_currentVersion()):
# uh-oh, something is seriously wrong
msg.append("CL script cache %s has version mismatch, may be corrupt?" %
fname)
fname)
elif oldVersion > _currentVersion():
msg.append(("CL script cache %s was created by " +
"a newer version of pyraf (cache %s, this pyraf %s)") %
(fname, `oldVersion`, `_currentVersion()`))
"a newer version of pyraf (cache %s, this pyraf %s)") %
(fname, repr(oldVersion), repr(_currentVersion())))
else:
msg.append("CL script cache %s is obsolete version (old %s, current %s)" %
(fname, `oldVersion`, `_currentVersion()`))
(fname, repr(oldVersion), repr(_currentVersion())))
fh.close()
# failed to open either cache
self.warning("\n".join(msg))
......@@ -261,7 +262,7 @@ class _CodeCache:
filename = task.getFullpath()
except (AttributeError, TypeError):
raise TypeError(
"Filename parameter must be a string or IrafCLTask")
"Filename parameter must be a string or IrafCLTask")
index = self.getIndex(filename)
# system cache is last in list
irange = range(len(self.cacheList))
......@@ -272,64 +273,26 @@ class _CodeCache:
if index in cache:
if writeflag:
del cache[index]
self.warning("Removed %s from CL script cache %s" % \
(filename,self.cacheFileList[i]), 2)
self.warning("Removed %s from CL script cache %s" %
(filename,self.cacheFileList[i]), 2)
nremoved = nremoved+1
else:
self.warning("Cannot remove %s from read-only "
"CL script cache %s" % \
(filename,self.cacheFileList[i]))
"CL script cache %s" %
(filename,self.cacheFileList[i]))
if nremoved==0:
self.warning("Did not find %s in CL script cache" % filename, 2)
# simple class to mimic pycode, for unit test (save us from importing others)
class DummyCodeObj:
def setFilename(self, f):
self.filename = f
def __str__(self):
retval = '<DummyCodeObj:'
if hasattr(self, 'filename'): retval += ' filename="'+self.filename+'"'
if hasattr(self, 'code'): retval += ' code="'+self.code+'"'
retval += '>'
return retval
def test():
""" Just run through the paces """
global codeCache
import os
print('Starting codeCache is: '+str(codeCache.cacheList))
print('keys = '+str(codeCache.clFileDict.keys()))
for fname in ('clcache.py', 'filecache.py'):
# lets cache this file
print('\ncaching: '+fname)
idx = codeCache.getIndex(fname)
pc = DummyCodeObj()
pc.code = 'print(123)'
print('fname:', fname, ', idx:', idx)
codeCache.add(idx, pc) # goes in here
codeCache.add(idx, pc) # NOT duplicated here
codeCache.add(idx, pc) # or here
print('And now, codeCache is: '+str(codeCache.cacheList))
print('keys = '+str(codeCache.clFileDict.keys()))
# try to get it out
newidx, newpycode = codeCache.get(fname)
assert newidx==idx, 'ERROR: was'+str(idx)+', but now is: '+str(newidx)
print('The -get- gave us: '+str(newpycode))
# create code cache
userCacheDir = os.path.join(userIrafHome,'pyraf')
if not os.path.exists(userCacheDir):
try:
os.mkdir(userCacheDir)
if '-s' not in sys.argv and '--silent' not in sys.argv:
print 'Created directory %s for cache' % userCacheDir
print('Created directory %s for cache' % userCacheDir)
except OSError:
print 'Could not create directory %s' % userCacheDir
print('Could not create directory %s' % userCacheDir)
dbfile = 'clcache'
......@@ -342,6 +305,3 @@ else:
os.path.join(pyrafglobals.pyrafDir,dbfile)])
del userCacheDir, dbfile
if __name__ == '__main__':
test()
......@@ -487,26 +487,3 @@ def getParser():
def parse(tokens, fname=None):
global _parser
return _parser.parse(tokens, fname=fname)
if __name__ == '__main__':
import time
import clscan
t0 = time.time()
# scan file 'simple.cl'
fnm = 'simple.cl'
lines = open(fnm).read()
scanner = clscan.CLScanner()
tokens = scanner.tokenize(lines)
t1 = time.time()
# parse
p = getParser()
tree = p.parse(tokens, fname=fnm)
t2 = time.time()
print 'Scan:', t1-t0, 'sec, Parse:', t2-t1, 'sec'
......@@ -986,13 +986,3 @@ def toklist(tlist,filename=None):
if filename:
sys.stdout.close()
sys.stdout = sys.__stdout__
if __name__ == '__main__':
s = CLScanner()
# scan file 'simple.cl'
lines = open('simple.cl').read()
tokens = s.tokenize(lines)
toklist(tokens[:30])
......@@ -24,7 +24,6 @@
from __future__ import division # confidence high
import string
from dis import opname, HAVE_ARGUMENT
# --------------------------------------------------------------------
......@@ -128,7 +127,7 @@ def describe(func, name = None):
def __getmethods(c, m):
for k, v in c.__dict__.items():
if type(v) == type(__getmethods): # and k[0] != "_":
if not k in m:
if k not in m:
m[k] = describe(v, k), c.__name__
for c in c.__bases__:
__getmethods(c, m)
......@@ -144,26 +143,3 @@ def describe_instance(self):
"Return a dictionary describing all methods available in an instance"
return describe_class(self.__class__)
#
# --------------------------------------------------------------------
if __name__ == "__main__":
def foo(a, b=1, *c, **d):
e = a + b + c
f = None
bar = lambda a: 0
# from Duncan Booth
def baz(a, (b, c) = ('foo','bar'), (d, e, f) = (None, None, None), g = None):
pass
print "describeParams(foo)", describeParams(foo)
print "describeParams(bar)", describeParams(bar)
print "describeParams(baz)", describeParams(baz)
print describe(foo)
print describe(bar)
print describe(baz)
......@@ -14,7 +14,7 @@ $Id$
R. White, 2000 January 20
"""
from __future__ import division
from __future__ import division, print_function
# define INDEF, yes, no, EOF, Verbose, IrafError, userIrafHome
......@@ -65,7 +65,7 @@ try:
except:
# basic usage does not actually require sscanf
sscanf = None
print "Warning: sscanf library not installed on "+sys.platform
print("Warning: sscanf library not installed on "+sys.platform)
try:
import cPickle as pickle
......@@ -656,7 +656,7 @@ def getTask(taskname, found=0):
# Try assuming fully qualified name first
task = _tasks.get(taskname)
if task is not None:
if Verbose>1: print 'found',taskname,'in task list'
if Verbose>1: print('found',taskname,'in task list')
return task
# Look it up in the minimum-match dictionary
......@@ -671,7 +671,7 @@ def getTask(taskname, found=0):
if len(fullname) == 1:
# unambiguous match
task = _tasks[fullname[0]]
if Verbose>1: print 'found',task.getName(),'in task list'
if Verbose>1: print('found',task.getName(),'in task list')
return task
# Ambiguous match is OK only if taskname is the full name
......@@ -799,13 +799,13 @@ def getVarList():
@handleRedirAndSaveKwds
def listAll(hidden=0):
"""List IRAF packages, tasks, and variables"""
print 'Packages:'
print('Packages:')
listPkgs()
print 'Loaded Packages:'
print('Loaded Packages:')
listLoaded()
print 'Tasks:'
print('Tasks:')
listTasks(hidden=hidden)
print 'Variables:'
print('Variables:')
listVars()
@handleRedirAndSaveKwds
......@@ -813,7 +813,7 @@ def listPkgs():
"""List IRAF packages"""
keylist = getPkgList()
if len(keylist) == 0:
print 'No IRAF packages defined'
print('No IRAF packages defined')
else:
keylist.sort()
# append '/' to identify packages
......@@ -825,7 +825,7 @@ def listLoaded():
"""List loaded IRAF packages"""
keylist = getLoadedList()
if len(keylist) == 0:
print 'No IRAF packages loaded'
print('No IRAF packages loaded')
else:
keylist.sort()
# append '/' to identify packages
......@@ -840,7 +840,7 @@ def listTasks(pkglist=None, hidden=0, **kw):
"""
keylist = getTaskList()
if len(keylist) == 0:
print 'No IRAF tasks defined'
print('No IRAF tasks defined')
return
# make a dictionary of pkgs to list
if pkglist is None:
......@@ -860,7 +860,7 @@ def listTasks(pkglist=None, hidden=0, **kw):
except KeyError, e:
_writeError(str(e))
if not len(pkgdict):
print 'No packages to list'
print('No packages to list')
return
# print each package separately
......@@ -879,12 +879,12 @@ def listTasks(pkglist=None, hidden=0, **kw):
tlist.append(task)
else:
if len(tlist) and lastpkg in pkgdict:
print lastpkg + '/:'
print(lastpkg + '/:')
_irafutils.printCols(tlist)
tlist = [task]
lastpkg = pkg
if len(tlist) and lastpkg in pkgdict:
print lastpkg + '/:'
print(lastpkg + '/:')
_irafutils.printCols(tlist)
@handleRedirAndSaveKwds
......@@ -898,23 +898,23 @@ def listCurrent(n=1, hidden=0):
plist[i] = loadedPath[-1-i].getName()
listTasks(plist,hidden=hidden)
else:
print 'No IRAF tasks defined'
print('No IRAF tasks defined')
@handleRedirAndSaveKwdsPlus
def listVars(prefix="", equals="\t= "):
"""List IRAF variables"""
keylist = getVarList()
if len(keylist) == 0:
print 'No IRAF variables defined'
print('No IRAF variables defined')
else:
keylist.sort()
for word in keylist:
print "%s%s%s%s" % (prefix, word, equals, envget(word))
print("%s%s%s%s" % (prefix, word, equals, envget(word)))
@handleRedirAndSaveKwds
def gripes():
""" Hide the system call - direct the user to support """
print "Please email your concern directly to support@stsci.edu"
print("Please email your concern directly to support@stsci.edu")
gripe = gripes
@handleRedirAndSaveKwds
......@@ -922,13 +922,13 @@ def which(*args):
""" Emulate the which function in IRAF. """
for arg in args:
try:
print getTask(arg).getPkgname()
print(getTask(arg).getPkgname())
# or: getTask(arg).getPkgname()+"."+getTask(arg).getName()
except _minmatch.AmbiguousKeyError, e:
print str(e)
print(str(e))
except (KeyError, TypeError):
if deftask(arg):
print 'language' # handle, e.g. 'which which', 'which cd'
print('language') # handle, e.g. 'which which', 'which cd'
else:
_writeError(arg+": task not found.")
......@@ -940,7 +940,7 @@ def whereis(*args):
if matches:
matches.reverse() # this reverse isn't necessary - they arrive
# in the right order, but CL seems to do this
print " ".join(matches)
print(" ".join(matches))
else:
_writeError(arg+": task not found.")
......@@ -1007,7 +1007,7 @@ def envget(var,default=None):
# Return a default value for TERM
# TERM gets caught as it is found in the default
# login.cl file setup by IRAF.
print "Using default TERM value for session."
print("Using default TERM value for session.")
return 'xterm'
else:
raise KeyError("Undefined environment variable `%s'" % var)
......@@ -1810,31 +1810,6 @@ def fscan(theLocals, line, *namelist, **kw):
_nscan = n_actual
return n_actual
def test_sscanf():
""" A basic unit test that sscanf was built/imported correctly and
can run. """
assert sscanf!=None, 'Error importing sscanf during iraffunctions init'
# aliveness
l = sscanf.sscanf("seven 6 4.0 -7", "%s %d %g %d")
assert l==['seven', 6, 4.0, -7], 'Unexpected! l = '+str(l)
# bad format
l = sscanf.sscanf("seven", "%d")
assert l==[], 'Unexpected! l = '+str(l)
# %c
l = sscanf.sscanf("seven", "%c%3c%99c")
assert l==['s', 'eve', 'n'], 'Unexpected! l = '+str(l)
# hex
l = sscanf.sscanf("0xabc90", "%x")
assert l==[703632], 'Unexpected! l = '+str(l)
# API error
try:
l = sscanf.sscanf()
except TypeError:
pass # this is expected - anything else should raise
# finished successfully
print 'test_sscanf successful'
def fscanf(theLocals, line, format, *namelist, **kw):
"""fscanf function sets parameters from a string/list parameter with format
......@@ -1943,7 +1918,7 @@ def scan(theLocals, *namelist, **kw):
args = (theLocals, repr(line),) + namelist
return fscan(*args, **kw)
except Exception, ex:
print 'iraf.scan exception: '+str(ex)
print('iraf.scan exception: '+str(ex))
finally:
# note return value not used here
rv = redirReset(resetList, closeFHList)
......@@ -1971,7 +1946,7 @@ def scanf(theLocals, format, *namelist, **kw):
args = (theLocals, repr(line), format,) + namelist
return fscanf(*args, **kw)
except Exception, ex:
print 'iraf.scanf exception: '+str(ex)
print('iraf.scanf exception: '+str(ex))
finally:
# note return value not used here
rv = redirReset(resetList, closeFHList)
......@@ -2035,11 +2010,11 @@ reset = set
def show(*args):
"""Print value of IRAF or OS environment variables"""
if len(args) and args[0].startswith("erract"):
print irafecl.erract.states()
print(irafecl.erract.states())
else:
if args:
for arg in args:
print envget(arg)
print(envget(arg))
else:
# print them all
listVars(" ", "=")
......@@ -2059,7 +2034,7 @@ def unset(*args):
@handleRedirAndSaveKwds
def time():
"""Print current time and date"""
print _time.strftime('%a %H:%M:%S %d-%b-%Y')
print(_time.strftime('%a %H:%M:%S %d-%b-%Y'))
# Note - we really should not give this a default (should require an int),
# because why run "sleep 0"?, but some legacy .cl scripts call it that way.
......@@ -2144,8 +2119,8 @@ def stty(terminal=None, **kw):
dftNlin = str(nlines)
except: pass # No error message here - may not always be available
# no args: print terminal type and size
print '%s ncols=%s nlines=%s' % (envget('terminal','undefined'),
envget('ttyncols',dftNcol), envget('ttynlines',dftNlin))
print('%s ncols=%s nlines=%s' % (envget('terminal','undefined'),
envget('ttyncols',dftNcol), envget('ttynlines',dftNlin)))
elif expkw['resize'] or expkw['terminal'] == "resize":
# resize: sets CL env parameters giving screen size; show errors
if _sys.stdout.isatty():
......@@ -2323,21 +2298,21 @@ def clear(*args):
def flprcache(*args):
"""Flush process cache. Takes optional list of tasknames."""
_irafexecute.processCache.flush(*args)
if Verbose>0: print "Flushed process cache"
if Verbose>0: print("Flushed process cache")
@handleRedirAndSaveKwds
def prcacheOff():
"""Disable process cache. No process cache will be employed
for the rest of this session."""
_irafexecute.processCache.setSize(0)
if Verbose>0: print "Disabled process cache"
if Verbose>0: print("Disabled process cache")
@handleRedirAndSaveKwds
def prcacheOn():
"""Re-enable process cache. A process cache will again be employed
for the rest of this session. This may be useful after prcacheOff()."""
_irafexecute.processCache.resetSize()
if Verbose>0: print "Enabled process cache"
if Verbose>0: print("Enabled process cache")
@handleRedirAndSaveKwds
def prcache(*args):
......@@ -2408,8 +2383,8 @@ def history(n=20):
@handleRedirAndSaveKwds
def ehistory(*args):
"""Dummy history function"""
print 'ehistory command not required: Use arrow keys to recall commands'
print 'or ctrl-R to search for a string in the command history.'
print('ehistory command not required: Use arrow keys to recall commands')
print('or ctrl-R to search for a string in the command history.')
# dummy routines (must allow *args and **kw)
......@@ -2681,7 +2656,7 @@ def package(pkgname=None, bin=None, PkgName='', PkgBinary='', **kw):
pkgname = pkg.getName()
if not pkgname in printed:
printed[pkgname] = 1
print ' %s' % pkgname
print(' %s' % pkgname)
rv1 = (PkgName, PkgBinary)
else:
spkgname = pkgname.replace('.', '_')
......@@ -2731,11 +2706,12 @@ def package(pkgname=None, bin=None, PkgName='', PkgBinary='', **kw):
@handleRedirAndSaveKwds
def clPrint(*args):
"""CL print command -- emulates CL spacing and uses redirection keywords"""
for arg in args:
print arg,
# don't put spaces after string arguments
if isinstance(arg,(str,unicode)): _sys.stdout.softspace=0
print
nargs = len(args)
for n, arg in enumerate(args, start=1):
print(arg, end='')
# add separator space, except after string arguments and at the end
if n < nargs and not isinstance(arg, (str, unicode)): print(end=' ')
print()
# printf format conversion utilities
......@@ -2882,7 +2858,7 @@ _backDir = None
@handleRedirAndSaveKwds
def pwd():
"""Print working directory"""
print _os.getcwd()
print(_os.getcwd())
@handleRedirAndSaveKwds
def chdir(directory=None):
......@@ -2899,7 +2875,7 @@ def chdir(directory=None):
if not isinstance(directory, (str,unicode)):
raise IrafError("Illegal non-string value for directory:"+ \
+repr(directory))
if Verbose > 2: print('chdir to: '+str(directory))
if Verbose > 2: print(('chdir to: '+str(directory)))
# Check for (1) local directory and (2) iraf variable
# when given an argument like 'dev'. In IRAF 'cd dev' is
# the same as 'cd ./dev' if there is a local directory named
......@@ -2933,7 +2909,7 @@ def back():
# OSError for getcwd() means current directory does not exist
_newBack = _backDir
_os.chdir(_backDir)
print _backDir
print(_backDir)
_irafexecute.processCache.setenv('chdir %s\n' % _backDir)
_backDir = _newBack
......@@ -2978,7 +2954,7 @@ def clCompatibilityMode(verbose=0, _save=0):
vmode = ' (verbose)'
else:
vmode = ''
print 'Entering CL-compatibility%s mode...' % vmode
print('Entering CL-compatibility%s mode...' % vmode)
# logging may be active if Monty is in use
if hasattr(__main__,'_pycmdline'):
......@@ -3026,9 +3002,9 @@ def clCompatibilityMode(verbose=0, _save=0):
logfile.write(code)
logfile.flush()
if verbose:
print '----- Python -----'
print code,
print '------------------'
print('----- Python -----')
print(code, end=' ')
print('------------------')
except EOFError:
break
except KeyboardInterrupt:
......@@ -3036,8 +3012,8 @@ def clCompatibilityMode(verbose=0, _save=0):
except:
_sys.stdout.flush()
traceback.print_exc()
print
print 'Leaving CL-compatibility mode...'
print()
print('Leaving CL-compatibility mode...')
# -----------------------------------------------------
# clArray: IRAF array class with type checking
......@@ -3262,7 +3238,7 @@ def IrafTaskFactory(prefix='', taskname=None, suffix='', value=None,
# new task is consistent with old task, so return old task
if task.getPkgbinary() != newtask.getPkgbinary():
# package binary differs -- add it to search path
if Verbose>1: print 'Adding',pkgbinary,'to',task,'path'
if Verbose>1: print('Adding',pkgbinary,'to',task,'path')
task.addPkgbinary(pkgbinary)
return task
# add it to the task list
......@@ -3348,7 +3324,7 @@ def IrafPkgFactory(prefix,taskname,suffix,value,pkgname,pkgbinary,redefine=0):
return newpkg
if pkg.getPkgbinary() != newpkg.getPkgbinary():
# only package binary differs -- add it to search path
if Verbose>1: print 'Adding',pkgbinary,'to',pkg,'path'
if Verbose>1: print('Adding',pkgbinary,'to',pkg,'path')
pkg.addPkgbinary(pkgbinary)
if pkgname != pkg.getPkgname():
# add existing task as an item in the new package
......
......@@ -1493,129 +1493,3 @@ def _readpar(filename,strict=0):
param_dict[par.name] = par
param_list.append(par)
return param_list
# -----------------------------------------------------------------------------
def test_IrafParList(fout = sys.stdout):
""" Test the IrafParList class """
# check our input (may be stdout)
assert hasattr(fout, 'write'), "Input not a file object: "+str(fout)
# create default, empty parlist for task 'bobs_task'
pl = IrafParList('bobs_pizza', 'bobs_pizza.par')
x = pl.getName()
assert x == 'bobs_pizza.par', "Unexpected name: "+str(x)
x = pl.getFilename()
assert x == 'bobs_pizza.par', "Unexpected fname: "+str(x)
x = pl.getPkgname()
assert x == '', "Unexpected pkg name: "+str(x)
assert not pl.hasPar('jojo'), "How did we get jojo?"
assert pl.hasPar('mode'), "We should have only: mode"
# length of 'empty' list is 2 - it has 'mode' and '$nargs'
assert len(pl) == 2, "Unexpected length: "+str(len(pl))
fout.write("lParam should show 1 par (mode)\n"+pl.lParamStr()+'\n')
# let's add some pars
par1 = basicpar.parFactory( \
('caller','s','a','Ima Hungry','',None,'person calling Bobs'), True)
x = par1.dpar().strip()
assert x == "caller = 'Ima Hungry'", "par1 is off: "+str(x)
par2 = basicpar.parFactory( \
('diameter','i','a','12','',None,'pizza size'), True)
x = par2.dpar().strip()
assert x == "diameter = 12", "par2 is off: "+str(x)
par3 = basicpar.parFactory( \
('pi','r','a','3.14159','',None,'Bob makes circles!'), True)
x = par3.dpar().strip()
assert x == "pi = 3.14159", "par3 is off: "+str(x)
par4 = basicpar.parFactory( \
('delivery','b','a','yes','',None,'delivery? (or pickup)'), True)
x = par4.dpar().strip()
assert x == "delivery = yes", "par4 is off: "+str(x)
par5 = basicpar.parFactory( \
('topping','s','a','peps','|toms|peps|olives',None,'the choices'), True)
x = par5.dpar().strip()
assert x == "topping = 'peps'", "par5 is off: "+str(x)
pl.addParam(par1)
assert len(pl) == 3, "Unexpected length: "+str(len(pl))
pl.addParam(par2)
pl.addParam(par3)
pl.addParam(par4)
pl.addParam(par5)
assert len(pl) == 7, "Unexpected length: "+str(len(pl))
# now we have a decent IrafParList to play with - test some
fout.write("lParam should show 6 actual pars (our 5 + mode)\n"+\
pl.lParamStr()+'\n')
assert pl.__doc__ == 'List of Iraf parameters',"__doc__ = "+str(pl.__doc__)
x = sorted(pl.getAllMatches(''))
assert x==['$nargs','caller','delivery','diameter','mode','pi','topping'],\
"Unexpected all: "+str(x)
x = sorted(pl.getAllMatches('d'))
assert x == ['delivery','diameter'], "Unexpected d's: "+str(x)
x = sorted(pl.getAllMatches('jojo'))
assert x == [], "Unexpected empty list: "+str(x)
x = pl.getParDict()
assert 'caller' in x, "Bad dict? "+str(x)
x = pl.getParList()
assert par1 in x, "Bad list? "+str(x)
assert pl.hasPar('topping'), "hasPar call failed"
# change a par val
pl.setParam('topping','olives') # should be no prob
assert 'olives' == pl.getParDict()['topping'].value, \
"Topping error: "+str(pl.getParDict()['topping'].value)
try:
# the following setParam should fail - not in choice list
pl.setParam('topping','peanutbutter') # oh the horror
raise RuntimeError("The bad setParam didn't fail?")
except ValueError:
pass
# Now try some direct access (also tests IrafPar basics)
assert pl.caller == "Ima Hungry", 'Ima? '+pl.getParDict()['caller'].value
pl.pi = 42
assert pl.pi == 42.0, "pl.pi not 42, ==> "+str(pl.pi)
try:
pl.pi = 'strings are not allowed' # should throw
raise RuntimeError("The bad pi assign didn't fail?")
except ValueError:
pass
pl.diameter = '9.7' # ok, string to float to int
assert pl.diameter == 9, "pl.diameter?, ==> "+str(pl.diameter)
try:
pl.diameter = 'twelve' # fails, not parseable to an int
raise RuntimeError("The bad diameter assign didn't fail?")
except ValueError:
pass
assert pl.diameter == 9, "pl.diameter after?, ==> "+str(pl.diameter)
pl.delivery = False # converts
assert pl.delivery == no, "pl.delivery not no? "+str(pl.delivery)
pl.delivery = 1 # converts
assert pl.delivery == yes, "pl.delivery not yes? "+str(pl.delivery)
pl.delivery = 'NO' # converts
assert pl.delivery == no, "pl.delivery not NO? "+str(pl.delivery)
try:
pl.delivery = "maybe, if he's not being recalcitrant"
raise RuntimeError("The bad delivery assign didn't fail?")
except ValueError:
pass
try:
pl.topping = 'peanutbutter' # try again
raise RuntimeError("The bad topping assign didn't fail?")
except ValueError:
pass
try:
x = pl.pumpkin_pie
raise RuntimeError("The pumpkin_pie access didn't fail?")
except KeyError:
pass
# If we get here, then all is well
# sys.exit(0)
fout.write("Test successful\n")
return pl
if __name__ == '__main__':
pl = test_IrafParList()
......@@ -211,28 +211,3 @@ class MsgIOBuffer(Frame):
self.msgIO.canvas.itemconfigure(1, height = scrollHgt)
self.msgIO.canvas.configure(scrollregion = (0, 0, 0, scrollHgt))
self.msgIO.canvas.yview_moveto(1)
# Test the MsgIOBuffer class
if __name__ == '__main__':
width = 500
height = 300
vheight = 50
text = "Tiptop"
top = Toplevel()
f = Frame(top, width = width, height = height, bg = "red")
m = MsgIOBuffer(top, width, vheight, text)
m.msgIO.pack(side=BOTTOM, fill = X)
f.pack(side = TOP, fill = BOTH, expand = TRUE)
for i in range(10):
t = "Text " + str(i)
m.updateIO(t)
m.updateIO("The quick brown fox jumps over the lazy dog with ease.")
m.updateIO("What is your quest?")
#inputValue = m.readline()
#print "inputValue = ", inputValue
top.mainloop()
......@@ -7,11 +7,10 @@
from __future__ import division # confidence high
# System level modules
import sys
import Tkinter as TKNTR # requires 2to3
# Our modules
from stsci.tools import irafutils, tkrotext
from stsci.tools import tkrotext
def is_USING_X():
......@@ -37,9 +36,9 @@ class MsgIOWidget(TKNTR.Frame):
# Create two sub-frames, one to hold the 1-liner msg I/O, and
# the other one to hold the whole scrollable history.
self._nowFrame = TKNTR.Frame(self, bd=2, relief=TKNTR.SUNKEN,
takefocus=False)
takefocus=False)
self._histFrame = TKNTR.Frame(self, bd=2, relief=TKNTR.SUNKEN,
takefocus=False)
takefocus=False)
# Put in the expand/collapse button (determine it's sizes)
self._expBttnHasTxt = True
......@@ -55,9 +54,9 @@ class MsgIOWidget(TKNTR.Frame):
btxt = ''
self._expBttnHasTxt = False
self._expBttn = TKNTR.Checkbutton(self._nowFrame, command=self._expand,
padx=px, pady=py,
text=btxt, indicatoron=0,
state = TKNTR.DISABLED)
padx=px, pady=py,
text=btxt, indicatoron=0,
state = TKNTR.DISABLED)
self._expBttn.pack(side=TKNTR.LEFT, padx=3)#, ipadx=0)
# Overlay a label on the frame
......@@ -66,23 +65,23 @@ class MsgIOWidget(TKNTR.Frame):
self._msgLabelMaxWidth = 65 # 70 works but causes plot redraws when
# the history panel is opened/closed
self._msgLabel = TKNTR.Label(self._nowFrame,
textvariable=self._msgLabelVar,
anchor=TKNTR.W,
justify=TKNTR.LEFT,
width=self._msgLabelMaxWidth,
wraplength=width-100,
takefocus=False)
textvariable=self._msgLabelVar,
anchor=TKNTR.W,
justify=TKNTR.LEFT,
width=self._msgLabelMaxWidth,
wraplength=width-100,
takefocus=False)
self._msgLabel.pack(side=TKNTR.LEFT,
fill=TKNTR.X,
expand=False)
self._msgLabel.bind('<Double-Button-1>', self._lblDblClk)
self._entry = TKNTR.Entry(self._nowFrame,
state=TKNTR.DISABLED,
width=1,
takefocus=False,
relief=TKNTR.FLAT,
highlightthickness=0)
state=TKNTR.DISABLED,
width=1,
takefocus=False,
relief=TKNTR.FLAT,
highlightthickness=0)
self._entry.pack(side=TKNTR.LEFT, fill=TKNTR.X, expand=True)
self._entry.bind('<Return>', self._enteredText)
self._entryTyping = TKNTR.BooleanVar()
......@@ -99,8 +98,9 @@ class MsgIOWidget(TKNTR.Frame):
self._histScrl.pack(side=TKNTR.RIGHT, fill=TKNTR.Y)
self._histText = tkrotext.ROText(self._histFrame, wrap=TKNTR.WORD,
takefocus=False,
height=10, yscrollcommand=self._histScrl.set)
takefocus=False,
height=10,
yscrollcommand=self._histScrl.set)
# (use if just TKNTR.Text) state=TKNTR.DISABLED, takefocus=False,
# exportselection=True is the default
self._histText.pack(side=TKNTR.TOP, fill=TKNTR.X, expand=True)
......@@ -114,7 +114,6 @@ class MsgIOWidget(TKNTR.Frame):
# At very end of ctor, add the init text to our history
self._appendToHistory(text)
def _lblDblClk(self, event=None):
if self._hasHistory:
# change the button appearance
......@@ -122,7 +121,6 @@ class MsgIOWidget(TKNTR.Frame):
# and then act as if it was clicked
self._expand()
def _expand(self):
ism = self._histFrame.winfo_ismapped()
if ism: # need to collapse
......@@ -136,7 +134,6 @@ class MsgIOWidget(TKNTR.Frame):
if self._hasHistory:
self._histText.see(TKNTR.END)
def updateIO(self, text=""):
""" Update the text portion of the scrolling canvas """
# Update the class variable with the latest text, and append the
......@@ -145,11 +142,10 @@ class MsgIOWidget(TKNTR.Frame):
self._msgLabelVar.set(text)
# this is a little debugging "easter egg"
if text.find('long debug line') >=0:
self.updateIO('and now we are going to talk and talk for a while'+\
self.updateIO('and now we are going to talk and talk for a while'+
' about nothing at all because we want a lot of text')
self._nowFrame.update_idletasks()
def readline(self):
""" Set focus to the entry widget and return it's contents """
# Find what had focus up to this point
......@@ -192,12 +188,10 @@ class MsgIOWidget(TKNTR.Frame):
# return the answer - important to have the "\n" on it
return ans+"\n"
def _enteredText(self, event=None):
self._entryTyping.set(False) # end the waiting
self._expBttn.focus_set()
def _appendToHistory(self, txt):
# sanity check - need no blank lines in the history
if len(txt.strip()) < 1:
......@@ -224,47 +218,3 @@ class MsgIOWidget(TKNTR.Frame):
# finally, make sure expand/collapse button is enabled now
self._expBttn.configure(state = TKNTR.NORMAL)
# Test the above class
if __name__ == '__main__':
import sys, time
m = None
def quit():
sys.exit()
def clicked():
m.updateIO("Clicked at "+time.asctime())
def ask():
m.updateIO("Type something in:")
out = m.readline()
# create the initial Tk window and immediately withdraw it
irafutils.init_tk_default_root()
# make our test window
top = TKNTR.Toplevel()
f = TKNTR.Frame(top, width=500, height=300)
b = TKNTR.Button(f, text='Click Me', command=clicked)
b.pack(side=TKNTR.LEFT, fill=TKNTR.X, expand=1)
q = TKNTR.Button(f, text='Buh-Bye', command=quit)
q.pack(side=TKNTR.LEFT)
f.pack(side=TKNTR.TOP, fill=TKNTR.X) # , expand=1)
p = TKNTR.Button(top, text='Prompt Me', command=ask)
p.pack(side=TKNTR.TOP, fill=TKNTR.X, expand=1)
fill = TKNTR.Frame(top, height=200, bg="green")
fill.pack(side=TKNTR.TOP, fill=TKNTR.BOTH, expand=1)
m = MsgIOWidget(top, 500, "Tiptop")
m.pack(side=TKNTR.BOTTOM, fill=TKNTR.X)
for i in range(10):
t = "Text " + str(i)
m.updateIO(t)
m.updateIO("What is your quest?")
inputValue = m.readline()
# start
top.mainloop()
This directory contains old test files for Chris Sontag
to run his custom diagnostic tests.
These tests (as of March 2018), if applicable, have been
ported to the "tests" directory. The ones here are not
run by CI and will not be modified to be in sync with
the ported counterparts. Use them at your own risk.
# NOTE: These currently do not work because there is no "simple.cl" file
# in the repository. For that reason, these were also not ported to
# "tests" for CI.
from __future__ import print_function
import time
from pyraf.cl2py import clscan, _parser, VarList, TypeCheck, Tree2Python
from pyraf.clparse import getParser
from pyraf.clscan import CLScanner, toklist
def test_cl2py():
t0 = time.time()
# scan file "simple.cl"
filename = "simple.cl"
lines = open(filename).read()
scanner = clscan.CLScanner()
tokens = scanner.tokenize(lines)
t1 = time.time()
# parse
tree = _parser.parse(tokens, fname=filename)
tree.filename = filename
t2 = time.time()
# first pass -- get variables
vars = VarList(tree)
# second pass -- check all expression types
# type info is added to tree
TypeCheck(tree, vars, '')
# third pass -- generate python code
pycode = Tree2Python(tree, vars)
t3 = time.time()
print("Scan:", t1-t0, "sec, Parse:", t2-t1, "sec")
print("CodeGen:", t3-t2, "sec")
def test_clparse():
t0 = time.time()
# scan file 'simple.cl'
fnm = 'simple.cl'
lines = open(fnm).read()
scanner = clscan.CLScanner()
tokens = scanner.tokenize(lines)
t1 = time.time()
# parse
p = getParser()
tree = p.parse(tokens, fname=fnm)
t2 = time.time()
print('Scan:', t1-t0, 'sec, Parse:', t2-t1, 'sec')
def test_clscan():
s = CLScanner()
# scan file 'simple.cl'
lines = open('simple.cl').read()
tokens = s.tokenize(lines)
toklist(tokens[:30])
from __future__ import division, print_function
from pyraf.clcache import codeCache
# simple class to mimic pycode, for unit test (save us from importing others)
class DummyCodeObj:
def setFilename(self, f):
self.filename = f
def __str__(self):
retval = '<DummyCodeObj:'
if hasattr(self, 'filename'): retval += ' filename="'+self.filename+'"'
if hasattr(self, 'code'): retval += ' code="'+self.code+'"'
retval += '>'
return retval
def test():
""" Just run through the paces """
#global codeCache
print('Starting codeCache is: '+str(codeCache.cacheList))
print('keys = '+str(codeCache.clFileDict.keys()))
for fname in ('../clcache.py', '../filecache.py'):
# lets cache this file
print('\ncaching: '+fname)
idx = codeCache.getIndex(fname)
pc = DummyCodeObj()
pc.code = 'print(123)'
print('fname:', fname, ', idx:', idx)
codeCache.add(idx, pc) # goes in here
codeCache.add(idx, pc) # NOT duplicated here
codeCache.add(idx, pc) # or here
print('And now, codeCache is: '+str(codeCache.cacheList))
print('keys = '+str(codeCache.clFileDict.keys()))
# try to get it out
newidx, newpycode = codeCache.get(fname)
assert newidx==idx, 'ERROR: was'+str(idx)+', but now is: '+str(newidx)
print('The -get- gave us: '+str(newpycode))
if __name__ == '__main__':
test()
from __future__ import print_function
from pyraf.describe import describe, describeParams
def test():
def foo(a, b=1, *c, **d):
e = a + b + c
f = None
bar = lambda a: 0 # noqa
# from Duncan Booth
def baz(a, (b, c) = ('foo','bar'), (d, e, f) = (None, None, None), g = None):
pass
print("describeParams(foo)", describeParams(foo))
print("describeParams(bar)", describeParams(bar))
print("describeParams(baz)", describeParams(baz))
print(describe(foo))
print(describe(bar))
print(describe(baz))
# TODO: These were not ported to "tests" for Jenkins CI because
# they are interactive.
import sys
import time
import Tkinter as TKNTR # requires 2to3
from Tkinter import * # requires 2to3
from stsci.tools import irafutils
from pyraf.msgiobuffer import MsgIOBuffer
from pyraf.msgiowidget import MsgIOWidget
from pyraf.splash import PyrafSplash
def test_buffer():
"""Test the MsgIOBuffer class"""
width = 500
height = 300
vheight = 50
text = "Tiptop"
top = Toplevel()
f = Frame(top, width = width, height = height, bg = "red")
m = MsgIOBuffer(top, width, vheight, text)
m.msgIO.pack(side=BOTTOM, fill = X)
f.pack(side = TOP, fill = BOTH, expand = TRUE)
for i in range(10):
t = "Text " + str(i)
m.updateIO(t)
m.updateIO("The quick brown fox jumps over the lazy dog with ease.")
m.updateIO("What is your quest?")
#inputValue = m.readline()
#print "inputValue = ", inputValue
top.mainloop()
def test_widget():
m = None
def quit():
sys.exit()
def clicked():
m.updateIO("Clicked at "+time.asctime())
def ask():
m.updateIO("Type something in:")
out = m.readline()
# create the initial Tk window and immediately withdraw it
irafutils.init_tk_default_root()
# make our test window
top = TKNTR.Toplevel()
f = TKNTR.Frame(top, width=500, height=300)
b = TKNTR.Button(f, text='Click Me', command=clicked)
b.pack(side=TKNTR.LEFT, fill=TKNTR.X, expand=1)
q = TKNTR.Button(f, text='Buh-Bye', command=quit)
q.pack(side=TKNTR.LEFT)
f.pack(side=TKNTR.TOP, fill=TKNTR.X) # , expand=1)
p = TKNTR.Button(top, text='Prompt Me', command=ask)
p.pack(side=TKNTR.TOP, fill=TKNTR.X, expand=1)
fill = TKNTR.Frame(top, height=200, bg="green")
fill.pack(side=TKNTR.TOP, fill=TKNTR.BOTH, expand=1)
m = MsgIOWidget(top, 500, "Tiptop")
m.pack(side=TKNTR.BOTTOM, fill=TKNTR.X)
for i in range(10):
t = "Text " + str(i)
m.updateIO(t)
m.updateIO("What is your quest?")
inputValue = m.readline()
# start
top.mainloop()
def test_splash():
s = PyrafSplash()
print("Sleeping 2 seconds...")
time.sleep(2)
s.Destroy()
from __future__ import print_function
from pyraf import sscanf
def test_sscanf():
""" A basic unit test that sscanf was built/imported correctly and
can run. """
assert sscanf is not None, 'Error importing sscanf during iraffunctions init'
# aliveness
l = sscanf.sscanf("seven 6 4.0 -7", "%s %d %g %d")
assert l==['seven', 6, 4.0, -7], 'Unexpected! l = '+str(l)
# bad format
l = sscanf.sscanf("seven", "%d")
assert l==[], 'Unexpected! l = '+str(l)
# %c
l = sscanf.sscanf("seven", "%c%3c%99c")
assert l==[<